Add transaction expiration tests
This commit is contained in:
		@@ -5,6 +5,7 @@ import {
 | 
			
		||||
    chaiSetup,
 | 
			
		||||
    constants,
 | 
			
		||||
    FillResults,
 | 
			
		||||
    getLatestBlockTimestampAsync,
 | 
			
		||||
    LogDecoder,
 | 
			
		||||
    OrderFactory,
 | 
			
		||||
    provider,
 | 
			
		||||
@@ -47,7 +48,7 @@ chaiSetup.configure();
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
 | 
			
		||||
// tslint:disable:no-unnecessary-type-assertion
 | 
			
		||||
describe.only('Exchange transactions', () => {
 | 
			
		||||
describe('Exchange transactions', () => {
 | 
			
		||||
    let chainId: number;
 | 
			
		||||
    let senderAddress: string;
 | 
			
		||||
    let owner: string;
 | 
			
		||||
@@ -163,7 +164,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                const order = await orderFactory.newSignedOrderAsync();
 | 
			
		||||
                const orders = [order];
 | 
			
		||||
                const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.FillOrder, orders);
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                const transactionReceipt = await exchangeWrapper.executeTransactionAsync(transaction, takerAddress);
 | 
			
		||||
                const transactionExecutionLogs = transactionReceipt.logs.filter(
 | 
			
		||||
                    log =>
 | 
			
		||||
@@ -178,6 +179,23 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                    executionLogArgs.transactionHash,
 | 
			
		||||
                );
 | 
			
		||||
            });
 | 
			
		||||
            it('should revert if the transaction is expired', async () => {
 | 
			
		||||
                const order = await orderFactory.newSignedOrderAsync();
 | 
			
		||||
                const orders = [order];
 | 
			
		||||
                const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.FillOrder, orders);
 | 
			
		||||
                const currentTimestamp = await getLatestBlockTimestampAsync();
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync({
 | 
			
		||||
                    data,
 | 
			
		||||
                    expirationTimeSeconds: new BigNumber(currentTimestamp).minus(10),
 | 
			
		||||
                });
 | 
			
		||||
                const transactionHashHex = transactionHashUtils.getTransactionHashHex(transaction);
 | 
			
		||||
                const expectedError = new ExchangeRevertErrors.TransactionError(
 | 
			
		||||
                    ExchangeRevertErrors.TransactionErrorCode.Expired,
 | 
			
		||||
                    transactionHashHex,
 | 
			
		||||
                );
 | 
			
		||||
                const tx = exchangeWrapper.executeTransactionAsync(transaction, senderAddress);
 | 
			
		||||
                return expect(tx).to.revertWith(expectedError);
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        describe('fill methods', () => {
 | 
			
		||||
            for (const fnName of [
 | 
			
		||||
@@ -188,7 +206,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                it(`${fnName} should revert if signature is invalid and not called by signer`, async () => {
 | 
			
		||||
                    const orders = [await orderFactory.newSignedOrderAsync()];
 | 
			
		||||
                    const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
 | 
			
		||||
                    const transaction = await takerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                    const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                    const v = ethUtil.toBuffer(transaction.signature.slice(0, 4));
 | 
			
		||||
                    const invalidR = ethUtil.sha3('invalidR');
 | 
			
		||||
                    const invalidS = ethUtil.sha3('invalidS');
 | 
			
		||||
@@ -208,7 +226,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                it(`${fnName} should be successful if signed by taker and called by sender`, async () => {
 | 
			
		||||
                    const orders = [await orderFactory.newSignedOrderAsync()];
 | 
			
		||||
                    const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
 | 
			
		||||
                    const transaction = await takerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                    const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                    const transactionReceipt = await exchangeWrapper.executeTransactionAsync(
 | 
			
		||||
                        transaction,
 | 
			
		||||
                        senderAddress,
 | 
			
		||||
@@ -233,7 +251,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                it(`${fnName} should be successful if called by taker without a transaction signature`, async () => {
 | 
			
		||||
                    const orders = [await orderFactory.newSignedOrderAsync()];
 | 
			
		||||
                    const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
 | 
			
		||||
                    const transaction = await takerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                    const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                    transaction.signature = constants.NULL_BYTES;
 | 
			
		||||
                    const transactionReceipt = await exchangeWrapper.executeTransactionAsync(transaction, takerAddress);
 | 
			
		||||
                    const fillLogs = transactionReceipt.logs.filter(
 | 
			
		||||
@@ -257,7 +275,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                    const order = await orderFactory.newSignedOrderAsync();
 | 
			
		||||
                    const orders = [order];
 | 
			
		||||
                    const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
 | 
			
		||||
                    const transaction = await takerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                    const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                    const returnData = await exchangeInstance.executeTransaction.callAsync(
 | 
			
		||||
                        transaction,
 | 
			
		||||
                        transaction.signature,
 | 
			
		||||
@@ -281,7 +299,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                it(`${fnName} should revert if transaction has already been executed`, async () => {
 | 
			
		||||
                    const orders = [await orderFactory.newSignedOrderAsync()];
 | 
			
		||||
                    const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
 | 
			
		||||
                    const transaction = await takerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                    const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                    await exchangeWrapper.executeTransactionAsync(transaction, senderAddress);
 | 
			
		||||
                    const transactionHashHex = transactionHashUtils.getTransactionHashHex(transaction);
 | 
			
		||||
                    const expectedError = new ExchangeRevertErrors.TransactionError(
 | 
			
		||||
@@ -294,13 +312,15 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                it(`${fnName} should revert and rethrow error if executeTransaction is called recursively with a signature`, async () => {
 | 
			
		||||
                    const orders = [await orderFactory.newSignedOrderAsync()];
 | 
			
		||||
                    const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
 | 
			
		||||
                    const transaction = await takerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                    const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                    const transactionHashHex = transactionHashUtils.getTransactionHashHex(transaction);
 | 
			
		||||
                    const recursiveData = exchangeInstance.executeTransaction.getABIEncodedTransactionData(
 | 
			
		||||
                        transaction,
 | 
			
		||||
                        transaction.signature,
 | 
			
		||||
                    );
 | 
			
		||||
                    const recursiveTransaction = await takerTransactionFactory.newSignedTransactionAsync(recursiveData);
 | 
			
		||||
                    const recursiveTransaction = await takerTransactionFactory.newSignedTransactionAsync({
 | 
			
		||||
                        data: recursiveData,
 | 
			
		||||
                    });
 | 
			
		||||
                    const recursiveTransactionHashHex = transactionHashUtils.getTransactionHashHex(
 | 
			
		||||
                        recursiveTransaction,
 | 
			
		||||
                    );
 | 
			
		||||
@@ -318,12 +338,14 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                it(`${fnName} should be successful if executeTransaction is called recursively by taker without a signature`, async () => {
 | 
			
		||||
                    const orders = [await orderFactory.newSignedOrderAsync()];
 | 
			
		||||
                    const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
 | 
			
		||||
                    const transaction = await takerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                    const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                    const recursiveData = exchangeInstance.executeTransaction.getABIEncodedTransactionData(
 | 
			
		||||
                        transaction,
 | 
			
		||||
                        constants.NULL_BYTES,
 | 
			
		||||
                    );
 | 
			
		||||
                    const recursiveTransaction = await takerTransactionFactory.newSignedTransactionAsync(recursiveData);
 | 
			
		||||
                    const recursiveTransaction = await takerTransactionFactory.newSignedTransactionAsync({
 | 
			
		||||
                        data: recursiveData,
 | 
			
		||||
                    });
 | 
			
		||||
                    const transactionReceipt = await exchangeWrapper.executeTransactionAsync(
 | 
			
		||||
                        recursiveTransaction,
 | 
			
		||||
                        takerAddress,
 | 
			
		||||
@@ -358,7 +380,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                        order.signature = constants.NULL_BYTES;
 | 
			
		||||
                        const orders = [order];
 | 
			
		||||
                        const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
 | 
			
		||||
                        const transaction = await takerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                        const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                        const transactionHashHex = transactionHashUtils.getTransactionHashHex(transaction);
 | 
			
		||||
                        const nestedError = new ExchangeRevertErrors.SignatureError(
 | 
			
		||||
                            ExchangeRevertErrors.SignatureErrorCode.InvalidLength,
 | 
			
		||||
@@ -381,7 +403,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                const order = await orderFactory.newSignedOrderAsync();
 | 
			
		||||
                const orders = [order];
 | 
			
		||||
                const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrder, orders);
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                const transactionHashHex = transactionHashUtils.getTransactionHashHex(transaction);
 | 
			
		||||
                const nestedError = new ExchangeRevertErrors.InvalidMakerError(
 | 
			
		||||
                    orderHashUtils.getOrderHashHex(order),
 | 
			
		||||
@@ -397,7 +419,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
            it('should be successful if signed by maker and called by sender', async () => {
 | 
			
		||||
                const orders = [await orderFactory.newSignedOrderAsync()];
 | 
			
		||||
                const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrder, orders);
 | 
			
		||||
                const transaction = await makerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                const transaction = await makerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                const transactionReceipt = await exchangeWrapper.executeTransactionAsync(transaction, senderAddress);
 | 
			
		||||
                const cancelLogs = transactionReceipt.logs.filter(
 | 
			
		||||
                    log => (log as LogWithDecodedArgs<ExchangeCancelEventArgs>).event === 'Cancel',
 | 
			
		||||
@@ -414,7 +436,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
            it('should be successful if called by maker without a signature', async () => {
 | 
			
		||||
                const orders = [await orderFactory.newSignedOrderAsync()];
 | 
			
		||||
                const data = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrder, orders);
 | 
			
		||||
                const transaction = await makerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                const transaction = await makerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                transaction.signature = constants.NULL_BYTES;
 | 
			
		||||
                const transactionReceipt = await exchangeWrapper.executeTransactionAsync(transaction, makerAddress);
 | 
			
		||||
                const cancelLogs = transactionReceipt.logs.filter(
 | 
			
		||||
@@ -437,7 +459,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                    ExchangeFunctionName.BatchCancelOrders,
 | 
			
		||||
                    orders,
 | 
			
		||||
                );
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                const transactionHashHex = transactionHashUtils.getTransactionHashHex(transaction);
 | 
			
		||||
                const nestedError = new ExchangeRevertErrors.InvalidMakerError(
 | 
			
		||||
                    orderHashUtils.getOrderHashHex(orders[0]),
 | 
			
		||||
@@ -456,7 +478,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                    ExchangeFunctionName.BatchCancelOrders,
 | 
			
		||||
                    orders,
 | 
			
		||||
                );
 | 
			
		||||
                const transaction = await makerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                const transaction = await makerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                const transactionReceipt = await exchangeWrapper.executeTransactionAsync(transaction, senderAddress);
 | 
			
		||||
                const cancelLogs = transactionReceipt.logs.filter(
 | 
			
		||||
                    log => (log as LogWithDecodedArgs<ExchangeCancelEventArgs>).event === 'Cancel',
 | 
			
		||||
@@ -478,7 +500,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                    ExchangeFunctionName.BatchCancelOrders,
 | 
			
		||||
                    orders,
 | 
			
		||||
                );
 | 
			
		||||
                const transaction = await makerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                const transaction = await makerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                transaction.signature = constants.NULL_BYTES;
 | 
			
		||||
                const transactionReceipt = await exchangeWrapper.executeTransactionAsync(transaction, makerAddress);
 | 
			
		||||
                const cancelLogs = transactionReceipt.logs.filter(
 | 
			
		||||
@@ -500,7 +522,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
            it('should be successful if signed by maker and called by sender', async () => {
 | 
			
		||||
                const targetEpoch = constants.ZERO_AMOUNT;
 | 
			
		||||
                const data = exchangeInstance.cancelOrdersUpTo.getABIEncodedTransactionData(targetEpoch);
 | 
			
		||||
                const transaction = await makerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                const transaction = await makerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                const transactionReceipt = await exchangeWrapper.executeTransactionAsync(transaction, senderAddress);
 | 
			
		||||
                const cancelLogs = transactionReceipt.logs.filter(
 | 
			
		||||
                    log => (log as LogWithDecodedArgs<ExchangeCancelUpToEventArgs>).event === 'CancelUpTo',
 | 
			
		||||
@@ -514,7 +536,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
            it('should be successful if called by maker without a signature', async () => {
 | 
			
		||||
                const targetEpoch = constants.ZERO_AMOUNT;
 | 
			
		||||
                const data = exchangeInstance.cancelOrdersUpTo.getABIEncodedTransactionData(targetEpoch);
 | 
			
		||||
                const transaction = await makerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                const transaction = await makerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                const transactionReceipt = await exchangeWrapper.executeTransactionAsync(transaction, makerAddress);
 | 
			
		||||
                const cancelLogs = transactionReceipt.logs.filter(
 | 
			
		||||
                    log => (log as LogWithDecodedArgs<ExchangeCancelUpToEventArgs>).event === 'CancelUpTo',
 | 
			
		||||
@@ -531,7 +553,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                const order = await orderFactory.newSignedOrderAsync();
 | 
			
		||||
                const orderHash = orderHashUtils.getOrderHashHex(order);
 | 
			
		||||
                const data = exchangeInstance.preSign.getABIEncodedTransactionData(orderHash);
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                let isPreSigned = await exchangeInstance.preSigned.callAsync(orderHash, takerAddress);
 | 
			
		||||
                expect(isPreSigned).to.be.eq(false);
 | 
			
		||||
                await exchangeWrapper.executeTransactionAsync(transaction, senderAddress);
 | 
			
		||||
@@ -542,7 +564,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                const order = await orderFactory.newSignedOrderAsync();
 | 
			
		||||
                const orderHash = orderHashUtils.getOrderHashHex(order);
 | 
			
		||||
                const data = exchangeInstance.preSign.getABIEncodedTransactionData(orderHash);
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                transaction.signature = constants.NULL_BYTES;
 | 
			
		||||
                let isPreSigned = await exchangeInstance.preSigned.callAsync(orderHash, takerAddress);
 | 
			
		||||
                expect(isPreSigned).to.be.eq(false);
 | 
			
		||||
@@ -558,7 +580,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                    validatorAddress,
 | 
			
		||||
                    shouldApprove,
 | 
			
		||||
                );
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                const transactionReceipt = await exchangeWrapper.executeTransactionAsync(transaction, senderAddress);
 | 
			
		||||
                const validatorApprovalLogs = transactionReceipt.logs.filter(
 | 
			
		||||
                    log =>
 | 
			
		||||
@@ -579,7 +601,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                    validatorAddress,
 | 
			
		||||
                    shouldApprove,
 | 
			
		||||
                );
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                transaction.signature = constants.NULL_BYTES;
 | 
			
		||||
                const transactionReceipt = await exchangeWrapper.executeTransactionAsync(transaction, takerAddress);
 | 
			
		||||
                const validatorApprovalLogs = transactionReceipt.logs.filter(
 | 
			
		||||
@@ -603,7 +625,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                    validatorAddress,
 | 
			
		||||
                    shouldApprove,
 | 
			
		||||
                );
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                const transactionReceipt = await exchangeWrapper.executeTransactionAsync(transaction, senderAddress);
 | 
			
		||||
                const validatorApprovalLogs = transactionReceipt.logs.filter(
 | 
			
		||||
                    log =>
 | 
			
		||||
@@ -624,7 +646,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                    validatorAddress,
 | 
			
		||||
                    shouldApprove,
 | 
			
		||||
                );
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                transaction.signature = constants.NULL_BYTES;
 | 
			
		||||
                const transactionReceipt = await exchangeWrapper.executeTransactionAsync(transaction, takerAddress);
 | 
			
		||||
                const validatorApprovalLogs = transactionReceipt.logs.filter(
 | 
			
		||||
@@ -647,8 +669,8 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                const order2 = await orderFactory.newSignedOrderAsync();
 | 
			
		||||
                const data1 = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.FillOrder, [order1]);
 | 
			
		||||
                const data2 = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.FillOrder, [order2]);
 | 
			
		||||
                const transaction1 = await takerTransactionFactory.newSignedTransactionAsync(data1);
 | 
			
		||||
                const transaction2 = await taker2TransactionFactory.newSignedTransactionAsync(data2);
 | 
			
		||||
                const transaction1 = await takerTransactionFactory.newSignedTransactionAsync({ data: data1 });
 | 
			
		||||
                const transaction2 = await taker2TransactionFactory.newSignedTransactionAsync({ data: data2 });
 | 
			
		||||
                const transactionReceipt = await exchangeWrapper.batchExecuteTransactionsAsync(
 | 
			
		||||
                    [transaction1, transaction2],
 | 
			
		||||
                    senderAddress,
 | 
			
		||||
@@ -711,8 +733,8 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                const order2 = await orderFactory.newSignedOrderAsync();
 | 
			
		||||
                const data1 = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.FillOrder, [order1]);
 | 
			
		||||
                const data2 = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.FillOrder, [order2]);
 | 
			
		||||
                const transaction1 = await takerTransactionFactory.newSignedTransactionAsync(data1);
 | 
			
		||||
                const transaction2 = await takerTransactionFactory.newSignedTransactionAsync(data2);
 | 
			
		||||
                const transaction1 = await takerTransactionFactory.newSignedTransactionAsync({ data: data1 });
 | 
			
		||||
                const transaction2 = await takerTransactionFactory.newSignedTransactionAsync({ data: data2 });
 | 
			
		||||
                transaction1.signature = constants.NULL_BYTES;
 | 
			
		||||
                transaction2.signature = constants.NULL_BYTES;
 | 
			
		||||
                const transactionReceipt = await exchangeWrapper.batchExecuteTransactionsAsync(
 | 
			
		||||
@@ -777,8 +799,8 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                const order2 = await orderFactory.newSignedOrderAsync();
 | 
			
		||||
                const data1 = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.FillOrder, [order1]);
 | 
			
		||||
                const data2 = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.FillOrder, [order2]);
 | 
			
		||||
                const transaction1 = await takerTransactionFactory.newSignedTransactionAsync(data1);
 | 
			
		||||
                const transaction2 = await taker2TransactionFactory.newSignedTransactionAsync(data2);
 | 
			
		||||
                const transaction1 = await takerTransactionFactory.newSignedTransactionAsync({ data: data1 });
 | 
			
		||||
                const transaction2 = await taker2TransactionFactory.newSignedTransactionAsync({ data: data2 });
 | 
			
		||||
                transaction2.signature = constants.NULL_BYTES;
 | 
			
		||||
                const transactionReceipt = await exchangeWrapper.batchExecuteTransactionsAsync(
 | 
			
		||||
                    [transaction1, transaction2],
 | 
			
		||||
@@ -842,8 +864,8 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                const order2 = await orderFactory.newSignedOrderAsync();
 | 
			
		||||
                const data1 = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.FillOrder, [order1]);
 | 
			
		||||
                const data2 = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.FillOrder, [order2]);
 | 
			
		||||
                const transaction1 = await takerTransactionFactory.newSignedTransactionAsync(data1);
 | 
			
		||||
                const transaction2 = await taker2TransactionFactory.newSignedTransactionAsync(data2);
 | 
			
		||||
                const transaction1 = await takerTransactionFactory.newSignedTransactionAsync({ data: data1 });
 | 
			
		||||
                const transaction2 = await taker2TransactionFactory.newSignedTransactionAsync({ data: data2 });
 | 
			
		||||
                const returnData = await exchangeInstance.batchExecuteTransactions.callAsync(
 | 
			
		||||
                    [transaction1, transaction2],
 | 
			
		||||
                    [transaction1.signature, transaction2.signature],
 | 
			
		||||
@@ -872,8 +894,8 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                const data2 = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrder, [
 | 
			
		||||
                    order2,
 | 
			
		||||
                ]);
 | 
			
		||||
                const transaction1 = await takerTransactionFactory.newSignedTransactionAsync(data1);
 | 
			
		||||
                const transaction2 = await makerTransactionFactory.newSignedTransactionAsync(data2);
 | 
			
		||||
                const transaction1 = await takerTransactionFactory.newSignedTransactionAsync({ data: data1 });
 | 
			
		||||
                const transaction2 = await makerTransactionFactory.newSignedTransactionAsync({ data: data2 });
 | 
			
		||||
                const transactionReceipt = await exchangeWrapper.batchExecuteTransactionsAsync(
 | 
			
		||||
                    [transaction1, transaction2],
 | 
			
		||||
                    senderAddress,
 | 
			
		||||
@@ -948,8 +970,8 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                const data2 = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrder, [
 | 
			
		||||
                    order2,
 | 
			
		||||
                ]);
 | 
			
		||||
                const transaction1 = await takerTransactionFactory.newSignedTransactionAsync(data1);
 | 
			
		||||
                const transaction2 = await makerTransactionFactory.newSignedTransactionAsync(data2);
 | 
			
		||||
                const transaction1 = await takerTransactionFactory.newSignedTransactionAsync({ data: data1 });
 | 
			
		||||
                const transaction2 = await makerTransactionFactory.newSignedTransactionAsync({ data: data2 });
 | 
			
		||||
                const returnData = await exchangeInstance.batchExecuteTransactions.callAsync(
 | 
			
		||||
                    [transaction1, transaction2],
 | 
			
		||||
                    [transaction1.signature, transaction2.signature],
 | 
			
		||||
@@ -971,8 +993,8 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                const order = await orderFactory.newSignedOrderAsync();
 | 
			
		||||
                const data1 = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.CancelOrder, [order]);
 | 
			
		||||
                const data2 = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.FillOrder, [order]);
 | 
			
		||||
                const transaction1 = await makerTransactionFactory.newSignedTransactionAsync(data1);
 | 
			
		||||
                const transaction2 = await takerTransactionFactory.newSignedTransactionAsync(data2);
 | 
			
		||||
                const transaction1 = await makerTransactionFactory.newSignedTransactionAsync({ data: data1 });
 | 
			
		||||
                const transaction2 = await takerTransactionFactory.newSignedTransactionAsync({ data: data2 });
 | 
			
		||||
                const tx = exchangeWrapper.batchExecuteTransactionsAsync([transaction1, transaction2], senderAddress);
 | 
			
		||||
                const nestedError = new ExchangeRevertErrors.OrderStatusError(
 | 
			
		||||
                    orderHashUtils.getOrderHashHex(order),
 | 
			
		||||
@@ -984,6 +1006,25 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                );
 | 
			
		||||
                return expect(tx).to.revertWith(expectedError);
 | 
			
		||||
            });
 | 
			
		||||
            it('should revert if a single transaction is expired', async () => {
 | 
			
		||||
                const order1 = await orderFactory.newSignedOrderAsync();
 | 
			
		||||
                const order2 = await orderFactory.newSignedOrderAsync();
 | 
			
		||||
                const data1 = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.FillOrder, [order1]);
 | 
			
		||||
                const data2 = exchangeDataEncoder.encodeOrdersToExchangeData(ExchangeFunctionName.FillOrder, [order2]);
 | 
			
		||||
                const currentTimestamp = await getLatestBlockTimestampAsync();
 | 
			
		||||
                const transaction1 = await takerTransactionFactory.newSignedTransactionAsync({ data: data1 });
 | 
			
		||||
                const transaction2 = await taker2TransactionFactory.newSignedTransactionAsync({
 | 
			
		||||
                    data: data2,
 | 
			
		||||
                    expirationTimeSeconds: new BigNumber(currentTimestamp).minus(10),
 | 
			
		||||
                });
 | 
			
		||||
                const tx = exchangeWrapper.batchExecuteTransactionsAsync([transaction1, transaction2], senderAddress);
 | 
			
		||||
                const expiredTransactionHash = transactionHashUtils.getTransactionHashHex(transaction2);
 | 
			
		||||
                const expectedError = new ExchangeRevertErrors.TransactionError(
 | 
			
		||||
                    ExchangeRevertErrors.TransactionErrorCode.Expired,
 | 
			
		||||
                    expiredTransactionHash,
 | 
			
		||||
                );
 | 
			
		||||
                expect(tx).to.revertWith(expectedError);
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        describe('examples', () => {
 | 
			
		||||
            describe('ExchangeWrapper', () => {
 | 
			
		||||
@@ -1010,7 +1051,9 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                    });
 | 
			
		||||
                    const targetOrderEpoch = orderSalt.plus(1);
 | 
			
		||||
                    const cancelData = exchangeInstance.cancelOrdersUpTo.getABIEncodedTransactionData(targetOrderEpoch);
 | 
			
		||||
                    const cancelTransaction = await makerTransactionFactory.newSignedTransactionAsync(cancelData);
 | 
			
		||||
                    const cancelTransaction = await makerTransactionFactory.newSignedTransactionAsync({
 | 
			
		||||
                        data: cancelData,
 | 
			
		||||
                    });
 | 
			
		||||
                    await exchangeWrapperContract.cancelOrdersUpTo.awaitTransactionSuccessAsync(
 | 
			
		||||
                        targetOrderEpoch,
 | 
			
		||||
                        cancelTransaction.salt,
 | 
			
		||||
@@ -1025,7 +1068,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                        takerAssetFillAmount,
 | 
			
		||||
                        signedOrder.signature,
 | 
			
		||||
                    );
 | 
			
		||||
                    const fillTransaction = await takerTransactionFactory.newSignedTransactionAsync(fillData);
 | 
			
		||||
                    const fillTransaction = await takerTransactionFactory.newSignedTransactionAsync({ data: fillData });
 | 
			
		||||
                    const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
			
		||||
                    const transactionHashHex = transactionHashUtils.getTransactionHashHex(fillTransaction);
 | 
			
		||||
                    const expectedError = new ExchangeRevertErrors.TransactionExecutionError(
 | 
			
		||||
@@ -1059,7 +1102,7 @@ describe.only('Exchange transactions', () => {
 | 
			
		||||
                        takerAssetFillAmount,
 | 
			
		||||
                        signedOrder.signature,
 | 
			
		||||
                    );
 | 
			
		||||
                    const transaction = await takerTransactionFactory.newSignedTransactionAsync(data);
 | 
			
		||||
                    const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
 | 
			
		||||
                    const logDecoder = new LogDecoder(web3Wrapper, artifacts);
 | 
			
		||||
                    const transactionReceipt = await logDecoder.getTxWithDecodedLogsAsync(
 | 
			
		||||
                        await exchangeWrapperContract.fillOrder.sendTransactionAsync(
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import { generatePseudoRandomSalt, transactionHashUtils } from '@0x/order-utils';
 | 
			
		||||
import { SignatureType, SignedZeroExTransaction } from '@0x/types';
 | 
			
		||||
import { SignatureType, SignedZeroExTransaction, ZeroExTransaction } from '@0x/types';
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
import * as ethUtil from 'ethereumjs-util';
 | 
			
		||||
 | 
			
		||||
@@ -19,9 +19,12 @@ export class TransactionFactory {
 | 
			
		||||
        this._signerBuff = ethUtil.privateToAddress(this._privateKey);
 | 
			
		||||
    }
 | 
			
		||||
    public async newSignedTransactionAsync(
 | 
			
		||||
        data: string,
 | 
			
		||||
        customTransactionParams: Partial<ZeroExTransaction>,
 | 
			
		||||
        signatureType: SignatureType = SignatureType.EthSign,
 | 
			
		||||
    ): Promise<SignedZeroExTransaction> {
 | 
			
		||||
        if (customTransactionParams.data === undefined) {
 | 
			
		||||
            throw new Error('Error: ZeroExTransaction data field must be supplied');
 | 
			
		||||
        }
 | 
			
		||||
        const tenMinutesInSeconds = 10 * 60;
 | 
			
		||||
        const currentBlockTimestamp = await getLatestBlockTimestampAsync();
 | 
			
		||||
        const salt = generatePseudoRandomSalt();
 | 
			
		||||
@@ -29,12 +32,13 @@ export class TransactionFactory {
 | 
			
		||||
        const transaction = {
 | 
			
		||||
            salt,
 | 
			
		||||
            signerAddress,
 | 
			
		||||
            data,
 | 
			
		||||
            data: customTransactionParams.data,
 | 
			
		||||
            expirationTimeSeconds: new BigNumber(currentBlockTimestamp).plus(tenMinutesInSeconds),
 | 
			
		||||
            domain: {
 | 
			
		||||
                verifyingContractAddress: this._exchangeAddress,
 | 
			
		||||
                chainId: this._chainId,
 | 
			
		||||
            },
 | 
			
		||||
            ...customTransactionParams,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        const transactionHashBuffer = transactionHashUtils.getTransactionHashBuffer(transaction);
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@ export enum AssetProxyDispatchErrorCode {
 | 
			
		||||
export enum TransactionErrorCode {
 | 
			
		||||
    NoReentrancy,
 | 
			
		||||
    AlreadyExecuted,
 | 
			
		||||
    Expired,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class SignatureError extends RevertError {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user