Add TEC integration tests

This commit is contained in:
Amir Bandeali
2019-02-21 16:57:03 -05:00
parent 2de9b862d8
commit 1de6bca12d
9 changed files with 496 additions and 89 deletions

View File

@@ -178,6 +178,7 @@ contract MixinTECApprovalVerifier is
selector == MARKET_SELL_ORDERS_NO_THROW_SELECTOR
) {
// Decode all orders
// solhint-disable indent
(orders) = abi.decode(
data.slice(4, data.length),
(LibOrder.Order[])

View File

@@ -23,6 +23,7 @@ import "../src/MixinSignatureValidator.sol";
import "../src/MixinTECApprovalVerifier.sol";
// solhint-disable no-empty-blocks
contract TestMixins is
MixinSignatureValidator,
MixinTECApprovalVerifier

View File

@@ -69,6 +69,7 @@
},
"dependencies": {
"@0x/base-contract": "^4.0.3",
"@0x/contracts-asset-proxy": "1.0.2",
"@0x/contracts-exchange-libs": "^1.0.5",
"@0x/contracts-exchange": "1.0.2",
"@0x/contracts-erc20": "1.0.2",

View File

@@ -27,7 +27,6 @@ import {
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
const timeBuffer = new BigNumber(1000);
describe('Mixins tests', () => {
let transactionSignerAddress: string;
@@ -64,12 +63,13 @@ describe('Mixins tests', () => {
salt: devConstants.ZERO_AMOUNT,
signature: devConstants.NULL_BYTES,
};
const transactionSignerPrivateKey = devConstants.TESTRPC_PRIVATE_KEYS[0];
const approvalSignerPrivateKey1 = devConstants.TESTRPC_PRIVATE_KEYS[1];
const approvalSignerPrivateKey2 = devConstants.TESTRPC_PRIVATE_KEYS[2];
const transactionSignerPrivateKey =
devConstants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(transactionSignerAddress)];
const approvalSignerPrivateKey1 = devConstants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(approvalSignerAddress1)];
const approvalSignerPrivateKey2 = devConstants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(approvalSignerAddress2)];
transactionFactory = new TECTransactionFactory(transactionSignerPrivateKey, mixins.address);
approvalFactory1 = new ApprovalFactory(approvalSignerPrivateKey1);
approvalFactory2 = new ApprovalFactory(approvalSignerPrivateKey2);
approvalFactory1 = new ApprovalFactory(approvalSignerPrivateKey1, mixins.address);
approvalFactory2 = new ApprovalFactory(approvalSignerPrivateKey2, mixins.address);
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
@@ -130,21 +130,21 @@ describe('Mixins tests', () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
[approval.signature],
{ from: transactionSignerAddress },
);
await mixins.assertValidTECApprovals.callAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
[approval.signature],
{ from: transactionSignerAddress },
);
});
@@ -157,21 +157,21 @@ describe('Mixins tests', () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
[approval.signature],
{ from: transactionSignerAddress },
);
await mixins.assertValidTECApprovals.callAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
[approval.signature],
{ from: transactionSignerAddress },
);
});
@@ -196,21 +196,21 @@ describe('Mixins tests', () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
[approval.signature],
{ from: approvalSignerAddress1 },
);
await mixins.assertValidTECApprovals.callAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
[approval.signature],
{ from: approvalSignerAddress1 },
);
});
@@ -235,19 +235,16 @@ describe('Mixins tests', () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
const approvalSignature = `${approval.approvalSignature.slice(
0,
4,
)}FFFFFFFF${approval.approvalSignature.slice(12)}`;
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approvalSignature],
[signature],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
@@ -257,7 +254,7 @@ describe('Mixins tests', () => {
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approvalSignature],
[signature],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
@@ -268,7 +265,7 @@ describe('Mixins tests', () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(timeBuffer);
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
@@ -276,7 +273,7 @@ describe('Mixins tests', () => {
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
[approval.signature],
{ from: transactionSignerAddress },
),
RevertReason.ApprovalExpired,
@@ -286,7 +283,7 @@ describe('Mixins tests', () => {
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
[approval.signature],
{ from: transactionSignerAddress },
),
RevertReason.ApprovalExpired,
@@ -297,7 +294,7 @@ describe('Mixins tests', () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
@@ -305,7 +302,7 @@ describe('Mixins tests', () => {
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
[approval.signature],
{ from: approvalSignerAddress2 },
),
RevertReason.InvalidSender,
@@ -315,7 +312,7 @@ describe('Mixins tests', () => {
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
[approval.signature],
{ from: approvalSignerAddress2 },
),
RevertReason.InvalidSender,
@@ -334,21 +331,21 @@ describe('Mixins tests', () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
[approval.signature],
{ from: transactionSignerAddress },
);
await mixins.assertValidTECApprovals.callAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
[approval.signature],
{ from: transactionSignerAddress },
);
});
@@ -360,21 +357,21 @@ describe('Mixins tests', () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
[approval.signature],
{ from: transactionSignerAddress },
);
await mixins.assertValidTECApprovals.callAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
[approval.signature],
{ from: transactionSignerAddress },
);
});
@@ -402,21 +399,21 @@ describe('Mixins tests', () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
[approval.signature],
{ from: transactionSignerAddress },
);
await mixins.assertValidTECApprovals.callAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
[approval.signature],
{ from: transactionSignerAddress },
);
});
@@ -425,7 +422,7 @@ describe('Mixins tests', () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval1 = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await mixins.assertValidTransactionOrdersApproval.callAsync(
@@ -433,14 +430,14 @@ describe('Mixins tests', () => {
orders,
transaction.signature,
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
[approval1.approvalSignature, approval2.approvalSignature],
[approval1.signature, approval2.signature],
{ from: transactionSignerAddress },
);
await mixins.assertValidTECApprovals.callAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
[approval1.approvalSignature, approval2.approvalSignature],
[approval1.signature, approval2.signature],
{ from: transactionSignerAddress },
);
});
@@ -465,21 +462,21 @@ describe('Mixins tests', () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval2.approvalSignature],
[approval2.signature],
{ from: approvalSignerAddress1 },
);
await mixins.assertValidTECApprovals.callAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval2.approvalSignature],
[approval2.signature],
{ from: approvalSignerAddress1 },
);
});
@@ -510,19 +507,16 @@ describe('Mixins tests', () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
const approvalSignature = `${approval.approvalSignature.slice(
0,
4,
)}FFFFFFFF${approval.approvalSignature.slice(12)}`;
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approvalSignature],
[signature],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
@@ -532,7 +526,7 @@ describe('Mixins tests', () => {
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approvalSignature],
[signature],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
@@ -543,20 +537,17 @@ describe('Mixins tests', () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval1 = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds);
const approvalSignature2 = `${approval2.approvalSignature.slice(
0,
4,
)}FFFFFFFF${approval2.approvalSignature.slice(12)}`;
const approvalSignature2 = `${approval2.signature.slice(0, 4)}FFFFFFFF${approval2.signature.slice(12)}`;
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
[approval1.approvalSignature, approvalSignature2],
[approval1.signature, approvalSignature2],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
@@ -566,7 +557,7 @@ describe('Mixins tests', () => {
transaction,
transaction.signature,
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
[approval1.approvalSignature, approvalSignature2],
[approval1.signature, approvalSignature2],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
@@ -577,12 +568,9 @@ describe('Mixins tests', () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds);
const approvalSignature2 = `${approval2.approvalSignature.slice(
0,
4,
)}FFFFFFFF${approval2.approvalSignature.slice(12)}`;
const approvalSignature2 = `${approval2.signature.slice(0, 4)}FFFFFFFF${approval2.signature.slice(12)}`;
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
@@ -610,8 +598,8 @@ describe('Mixins tests', () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds1 = new BigNumber(currentTimestamp).plus(timeBuffer);
const approvalExpirationTimeSeconds2 = new BigNumber(currentTimestamp).minus(timeBuffer);
const approvalExpirationTimeSeconds1 = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approvalExpirationTimeSeconds2 = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
const approval1 = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds1);
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds2);
expectContractCallFailedAsync(
@@ -620,7 +608,7 @@ describe('Mixins tests', () => {
orders,
transaction.signature,
[approvalExpirationTimeSeconds1, approvalExpirationTimeSeconds2],
[approval1.approvalSignature, approval2.approvalSignature],
[approval1.signature, approval2.signature],
{ from: transactionSignerAddress },
),
RevertReason.ApprovalExpired,
@@ -630,7 +618,7 @@ describe('Mixins tests', () => {
transaction,
transaction.signature,
[approvalExpirationTimeSeconds1, approvalExpirationTimeSeconds2],
[approval1.approvalSignature, approval2.approvalSignature],
[approval1.signature, approval2.signature],
{ from: transactionSignerAddress },
),
RevertReason.ApprovalExpired,
@@ -641,7 +629,7 @@ describe('Mixins tests', () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(timeBuffer);
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds);
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
@@ -649,7 +637,7 @@ describe('Mixins tests', () => {
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval2.approvalSignature],
[approval2.signature],
{ from: approvalSignerAddress1 },
),
RevertReason.ApprovalExpired,
@@ -659,7 +647,7 @@ describe('Mixins tests', () => {
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval2.approvalSignature],
[approval2.signature],
{ from: approvalSignerAddress1 },
),
RevertReason.ApprovalExpired,
@@ -670,7 +658,7 @@ describe('Mixins tests', () => {
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval1 = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
@@ -678,7 +666,7 @@ describe('Mixins tests', () => {
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval1.approvalSignature],
[approval1.signature],
{ from: approvalSignerAddress2 },
),
RevertReason.InvalidSender,
@@ -688,7 +676,7 @@ describe('Mixins tests', () => {
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval1.approvalSignature],
[approval1.signature],
{ from: approvalSignerAddress2 },
),
RevertReason.InvalidSender,
@@ -723,3 +711,4 @@ describe('Mixins tests', () => {
});
});
});
// tslint:disable:max-file-line-count

View File

@@ -1,25 +1,56 @@
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
import { ExchangeContract } from '@0x/contracts-exchange';
import { chaiSetup, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils';
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
import {
artifacts as exchangeArtifacts,
ExchangeCancelEventArgs,
ExchangeCancelUpToEventArgs,
ExchangeContract,
ExchangeFillEventArgs,
} from '@0x/contracts-exchange';
import {
chaiSetup,
constants as devConstants,
expectContractCallFailedAsync,
getLatestBlockTimestampAsync,
OrderFactory,
provider,
TransactionFactory,
txDefaults,
web3Wrapper,
} from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
import { RevertReason, SignedOrder } from '@0x/types';
import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
import * as _ from 'lodash';
import { LogWithDecodedArgs } from 'ethereum-types';
import { TECContract } from '../src';
import { ApprovalFactory, artifacts, constants, exchangeDataEncoder, TECContract } from '../src';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
web3Wrapper.abiDecoder.addABI(exchangeArtifacts.Exchange.compilerOutput.abi);
// tslint:disable:no-unnecessary-type-assertion
describe('TEC tests', () => {
let makerAddress: string;
let owner: string;
let takerAddress: string;
let feeRecipientAddress: string;
// let erc20Proxy: ERC20ProxyContract;
let erc20Proxy: ERC20ProxyContract;
let erc20TokenA: DummyERC20TokenContract;
let erc20TokenB: DummyERC20TokenContract;
let zrxToken: DummyERC20TokenContract;
let tecContract: TECContract;
let exchange: ExchangeContract;
let erc20Wrapper: ERC20Wrapper;
let orderFactory: OrderFactory;
let takerTransactionFactory: TransactionFactory;
let makerTransactionFactory: TransactionFactory;
let approvalFactory: ApprovalFactory;
before(async () => {
await blockchainLifecycle.startAsync();
});
@@ -28,9 +59,58 @@ describe('TEC tests', () => {
});
before(async () => {
const accounts = await web3Wrapper.getAvailableAddressesAsync();
const usedAddresses = ([owner, makerAddress, takerAddress, feeRecipientAddress] = _.slice(accounts, 0, 4));
const usedAddresses = ([owner, makerAddress, takerAddress, feeRecipientAddress] = accounts.slice(0, 4));
erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner);
erc20Proxy = await erc20Wrapper.deployProxyAsync();
const numDummyErc20ToDeploy = 3;
[erc20TokenA, erc20TokenB, zrxToken] = await erc20Wrapper.deployDummyTokensAsync(
numDummyErc20ToDeploy,
devConstants.DUMMY_TOKEN_DECIMALS,
);
await erc20Wrapper.setBalancesAndAllowancesAsync();
exchange = await ExchangeContract.deployFrom0xArtifactAsync(
exchangeArtifacts.Exchange,
provider,
txDefaults,
assetDataUtils.encodeERC20AssetData(zrxToken.address),
);
await web3Wrapper.awaitTransactionSuccessAsync(
await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, { from: owner }),
devConstants.AWAIT_TRANSACTION_MINED_MS,
);
await web3Wrapper.awaitTransactionSuccessAsync(
await exchange.registerAssetProxy.sendTransactionAsync(erc20Proxy.address, { from: owner }),
devConstants.AWAIT_TRANSACTION_MINED_MS,
);
tecContract = await TECContract.deployFrom0xArtifactAsync(
artifacts.TEC,
provider,
txDefaults,
exchange.address,
);
// Configure order defaults
const defaultOrderParams = {
...devConstants.STATIC_ORDER_PARAMS,
exchangeAddress: exchange.address,
senderAddress: tecContract.address,
makerAddress,
feeRecipientAddress,
makerAssetData: assetDataUtils.encodeERC20AssetData(erc20TokenA.address),
takerAssetData: assetDataUtils.encodeERC20AssetData(erc20TokenB.address),
};
const makerPrivateKey = devConstants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)];
const takerPrivateKey = devConstants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(takerAddress)];
const feeRecipientPrivateKey = devConstants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(feeRecipientAddress)];
orderFactory = new OrderFactory(makerPrivateKey, defaultOrderParams);
makerTransactionFactory = new TransactionFactory(makerPrivateKey, exchange.address);
takerTransactionFactory = new TransactionFactory(takerPrivateKey, exchange.address);
approvalFactory = new ApprovalFactory(feeRecipientPrivateKey, tecContract.address);
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
@@ -38,4 +118,332 @@ describe('TEC tests', () => {
afterEach(async () => {
await blockchainLifecycle.revertAsync();
});
describe('single order fills', () => {
for (const fnName of constants.SINGLE_FILL_FN_NAMES) {
it(`${fnName} should fill the order with a signed approval`, async () => {
const orders = [await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(transaction, approvalExpirationTimeSeconds);
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await tecContract.executeTransaction.sendTransactionAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: takerAddress },
),
devConstants.AWAIT_TRANSACTION_MINED_MS,
);
const fillLogs = transactionReceipt.logs.filter(
log => (log as LogWithDecodedArgs<ExchangeFillEventArgs>).event === 'Fill',
);
expect(fillLogs.length).to.eq(1);
const fillLogArgs = (fillLogs[0] as LogWithDecodedArgs<ExchangeFillEventArgs>).args;
expect(fillLogArgs.makerAddress).to.eq(makerAddress);
expect(fillLogArgs.takerAddress).to.eq(takerAddress);
expect(fillLogArgs.senderAddress).to.eq(tecContract.address);
expect(fillLogArgs.feeRecipientAddress).to.eq(feeRecipientAddress);
expect(fillLogArgs.makerAssetData).to.eq(orders[0].makerAssetData);
expect(fillLogArgs.takerAssetData).to.eq(orders[0].takerAssetData);
expect(fillLogArgs.makerAssetFilledAmount).to.bignumber.eq(orders[0].makerAssetAmount);
expect(fillLogArgs.takerAssetFilledAmount).to.bignumber.eq(orders[0].takerAssetAmount);
expect(fillLogArgs.makerFeePaid).to.bignumber.eq(orders[0].makerFee);
expect(fillLogArgs.takerFeePaid).to.bignumber.eq(orders[0].takerFee);
expect(fillLogArgs.orderHash).to.eq(orderHashUtils.getOrderHashHex(orders[0]));
});
it(`${fnName} should fill the order if called by approver`, async () => {
const orders = [await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await tecContract.executeTransaction.sendTransactionAsync(
transaction,
transaction.signature,
[],
[],
{ from: feeRecipientAddress },
),
devConstants.AWAIT_TRANSACTION_MINED_MS,
);
const fillLogs = transactionReceipt.logs.filter(
log => (log as LogWithDecodedArgs<ExchangeFillEventArgs>).event === 'Fill',
);
expect(fillLogs.length).to.eq(1);
const fillLogArgs = (fillLogs[0] as LogWithDecodedArgs<ExchangeFillEventArgs>).args;
expect(fillLogArgs.makerAddress).to.eq(makerAddress);
expect(fillLogArgs.takerAddress).to.eq(takerAddress);
expect(fillLogArgs.senderAddress).to.eq(tecContract.address);
expect(fillLogArgs.feeRecipientAddress).to.eq(feeRecipientAddress);
expect(fillLogArgs.makerAssetData).to.eq(orders[0].makerAssetData);
expect(fillLogArgs.takerAssetData).to.eq(orders[0].takerAssetData);
expect(fillLogArgs.makerAssetFilledAmount).to.bignumber.eq(orders[0].makerAssetAmount);
expect(fillLogArgs.takerAssetFilledAmount).to.bignumber.eq(orders[0].takerAssetAmount);
expect(fillLogArgs.makerFeePaid).to.bignumber.eq(orders[0].makerFee);
expect(fillLogArgs.takerFeePaid).to.bignumber.eq(orders[0].takerFee);
expect(fillLogArgs.orderHash).to.eq(orderHashUtils.getOrderHashHex(orders[0]));
});
it(`${fnName} should revert with no approval signature`, async () => {
const orders = [await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
await expectContractCallFailedAsync(
tecContract.executeTransaction.sendTransactionAsync(transaction, transaction.signature, [], [], {
from: takerAddress,
}),
RevertReason.InvalidApprovalSignature,
);
});
it(`${fnName} should revert with an invalid approval signature`, async () => {
const orders = [await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(transaction, approvalExpirationTimeSeconds);
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
await expectContractCallFailedAsync(
tecContract.executeTransaction.sendTransactionAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[signature],
{ from: takerAddress },
),
RevertReason.InvalidApprovalSignature,
);
});
it(`${fnName} should revert with an expired approval`, async () => {
const orders = [await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await expectContractCallFailedAsync(
tecContract.executeTransaction.sendTransactionAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: takerAddress },
),
RevertReason.ApprovalExpired,
);
});
it(`${fnName} should revert if not called by tx signer or approver`, async () => {
const orders = [await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await expectContractCallFailedAsync(
tecContract.executeTransaction.sendTransactionAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: owner },
),
RevertReason.InvalidSender,
);
});
}
});
describe('batch order fills', () => {
for (const fnName of [...constants.MARKET_FILL_FN_NAMES, ...constants.BATCH_FILL_FN_NAMES]) {
it(`${fnName} should fill the orders with a signed approval`, async () => {
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(transaction, approvalExpirationTimeSeconds);
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await tecContract.executeTransaction.sendTransactionAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: takerAddress },
),
devConstants.AWAIT_TRANSACTION_MINED_MS,
);
const fillLogs = transactionReceipt.logs.filter(
log => (log as LogWithDecodedArgs<ExchangeFillEventArgs>).event === 'Fill',
);
expect(fillLogs.length).to.eq(orders.length);
orders.forEach((order, index) => {
const fillLogArgs = (fillLogs[index] as LogWithDecodedArgs<ExchangeFillEventArgs>).args;
expect(fillLogArgs.makerAddress).to.eq(makerAddress);
expect(fillLogArgs.takerAddress).to.eq(takerAddress);
expect(fillLogArgs.senderAddress).to.eq(tecContract.address);
expect(fillLogArgs.feeRecipientAddress).to.eq(feeRecipientAddress);
expect(fillLogArgs.makerAssetData).to.eq(order.makerAssetData);
expect(fillLogArgs.takerAssetData).to.eq(order.takerAssetData);
expect(fillLogArgs.makerAssetFilledAmount).to.bignumber.eq(order.makerAssetAmount);
expect(fillLogArgs.takerAssetFilledAmount).to.bignumber.eq(order.takerAssetAmount);
expect(fillLogArgs.makerFeePaid).to.bignumber.eq(order.makerFee);
expect(fillLogArgs.takerFeePaid).to.bignumber.eq(order.takerFee);
expect(fillLogArgs.orderHash).to.eq(orderHashUtils.getOrderHashHex(order));
});
});
it(`${fnName} should fill the orders if called by approver`, async () => {
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await tecContract.executeTransaction.sendTransactionAsync(
transaction,
transaction.signature,
[],
[],
{ from: feeRecipientAddress },
),
devConstants.AWAIT_TRANSACTION_MINED_MS,
);
const fillLogs = transactionReceipt.logs.filter(
log => (log as LogWithDecodedArgs<ExchangeFillEventArgs>).event === 'Fill',
);
expect(fillLogs.length).to.eq(orders.length);
orders.forEach((order, index) => {
const fillLogArgs = (fillLogs[index] as LogWithDecodedArgs<ExchangeFillEventArgs>).args;
expect(fillLogArgs.makerAddress).to.eq(makerAddress);
expect(fillLogArgs.takerAddress).to.eq(takerAddress);
expect(fillLogArgs.senderAddress).to.eq(tecContract.address);
expect(fillLogArgs.feeRecipientAddress).to.eq(feeRecipientAddress);
expect(fillLogArgs.makerAssetData).to.eq(order.makerAssetData);
expect(fillLogArgs.takerAssetData).to.eq(order.takerAssetData);
expect(fillLogArgs.makerAssetFilledAmount).to.bignumber.eq(order.makerAssetAmount);
expect(fillLogArgs.takerAssetFilledAmount).to.bignumber.eq(order.takerAssetAmount);
expect(fillLogArgs.makerFeePaid).to.bignumber.eq(order.makerFee);
expect(fillLogArgs.takerFeePaid).to.bignumber.eq(order.takerFee);
expect(fillLogArgs.orderHash).to.eq(orderHashUtils.getOrderHashHex(order));
});
});
it(`${fnName} should revert with an invalid approval signature`, async () => {
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(transaction, approvalExpirationTimeSeconds);
const signature = `${approval.signature.slice(0, 4)}FFFFFFFF${approval.signature.slice(12)}`;
await expectContractCallFailedAsync(
tecContract.executeTransaction.sendTransactionAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[signature],
{ from: takerAddress },
),
RevertReason.InvalidApprovalSignature,
);
});
it(`${fnName} should revert with an expired approval`, async () => {
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await expectContractCallFailedAsync(
tecContract.executeTransaction.sendTransactionAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: takerAddress },
),
RevertReason.ApprovalExpired,
);
});
it(`${fnName} should revert if not called by tx signer or approver`, async () => {
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = takerTransactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await expectContractCallFailedAsync(
tecContract.executeTransaction.sendTransactionAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.signature],
{ from: owner },
),
RevertReason.InvalidSender,
);
});
}
});
describe('cancels', () => {
it('cancelOrder call should be successful without an approval', async () => {
const orders = [await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDERS, orders);
const transaction = makerTransactionFactory.newSignedTransaction(data);
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await tecContract.executeTransaction.sendTransactionAsync(transaction, transaction.signature, [], [], {
from: makerAddress,
}),
);
const cancelLogs = transactionReceipt.logs.filter(
log => (log as LogWithDecodedArgs<ExchangeCancelEventArgs>).event === 'Cancel',
);
expect(cancelLogs.length).to.eq(1);
const cancelLogArgs = (cancelLogs[0] as LogWithDecodedArgs<ExchangeCancelEventArgs>).args;
expect(cancelLogArgs.makerAddress).to.eq(makerAddress);
expect(cancelLogArgs.senderAddress).to.eq(tecContract.address);
expect(cancelLogArgs.feeRecipientAddress).to.eq(feeRecipientAddress);
expect(cancelLogArgs.makerAssetData).to.eq(orders[0].makerAssetData);
expect(cancelLogArgs.takerAssetData).to.eq(orders[0].takerAssetData);
expect(cancelLogArgs.orderHash).to.eq(orderHashUtils.getOrderHashHex(orders[0]));
});
it('batchCancelOrders call should be successful without an approval', async () => {
const orders = [await orderFactory.newSignedOrderAsync(), await orderFactory.newSignedOrderAsync()];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.BATCH_CANCEL_ORDERS, orders);
const transaction = makerTransactionFactory.newSignedTransaction(data);
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await tecContract.executeTransaction.sendTransactionAsync(transaction, transaction.signature, [], [], {
from: makerAddress,
}),
);
const cancelLogs = transactionReceipt.logs.filter(
log => (log as LogWithDecodedArgs<ExchangeCancelEventArgs>).event === 'Cancel',
);
expect(cancelLogs.length).to.eq(orders.length);
orders.forEach((order, index) => {
const cancelLogArgs = (cancelLogs[index] as LogWithDecodedArgs<ExchangeCancelEventArgs>).args;
expect(cancelLogArgs.makerAddress).to.eq(makerAddress);
expect(cancelLogArgs.senderAddress).to.eq(tecContract.address);
expect(cancelLogArgs.feeRecipientAddress).to.eq(feeRecipientAddress);
expect(cancelLogArgs.makerAssetData).to.eq(order.makerAssetData);
expect(cancelLogArgs.takerAssetData).to.eq(order.takerAssetData);
expect(cancelLogArgs.orderHash).to.eq(orderHashUtils.getOrderHashHex(order));
});
});
it('cancelOrdersUpTo call should be successful without an approval', async () => {
const orders: SignedOrder[] = [];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDERS_UP_TO, orders);
const transaction = makerTransactionFactory.newSignedTransaction(data);
const transactionReceipt = await web3Wrapper.awaitTransactionSuccessAsync(
await tecContract.executeTransaction.sendTransactionAsync(transaction, transaction.signature, [], [], {
from: makerAddress,
}),
);
const cancelLogs = transactionReceipt.logs.filter(
log => (log as LogWithDecodedArgs<ExchangeCancelUpToEventArgs>).event === 'CancelUpTo',
);
expect(cancelLogs.length).to.eq(1);
const cancelLogArgs = (cancelLogs[0] as LogWithDecodedArgs<ExchangeCancelUpToEventArgs>).args;
expect(cancelLogArgs.makerAddress).to.eq(makerAddress);
expect(cancelLogArgs.senderAddress).to.eq(tecContract.address);
expect(cancelLogArgs.orderEpoch).to.bignumber.eq(new BigNumber(1));
});
});
});

View File

@@ -6,22 +6,26 @@ import { hashUtils, SignedTECApproval, signingUtils, TECSignatureType } from './
export class ApprovalFactory {
private readonly _privateKey: Buffer;
constructor(privateKey: Buffer) {
private readonly _verifyingContractAddress: string;
constructor(privateKey: Buffer, verifyingContractAddress: string) {
this._privateKey = privateKey;
this._verifyingContractAddress = verifyingContractAddress;
}
public newSignedApproval(
transaction: SignedZeroExTransaction,
approvalExpirationTimeSeconds: BigNumber,
signatureType: TECSignatureType = TECSignatureType.EthSign,
): SignedTECApproval {
const approvalHashBuff = hashUtils.getApprovalHashBuffer(transaction, approvalExpirationTimeSeconds);
const tecTransaction = {
...transaction,
verifyingContractAddress: this._verifyingContractAddress,
};
const approvalHashBuff = hashUtils.getApprovalHashBuffer(tecTransaction, approvalExpirationTimeSeconds);
const signatureBuff = signingUtils.signMessage(approvalHashBuff, this._privateKey, signatureType);
const transactionHash = hashUtils.getTransactionHashHex(transaction);
const signedApproval = {
transactionHash,
transaction: tecTransaction,
approvalExpirationTimeSeconds,
transactionSignature: transaction.signature,
approvalSignature: ethUtil.addHexPrefix(signatureBuff.toString('hex')),
signature: ethUtil.addHexPrefix(signatureBuff.toString('hex')),
};
return signedApproval;
}

View File

@@ -1,3 +1,5 @@
import { BigNumber } from '@0x/utils';
export const constants = {
TEC_DOMAIN_NAME: '0x Protocol Trade Execution Coordinator',
TEC_DOMAIN_VERSION: '1.0.0',
@@ -16,4 +18,5 @@ export const constants = {
CANCEL_ORDERS: 'cancelOrders',
BATCH_CANCEL_ORDERS: 'batchCancelOrders',
CANCEL_ORDERS_UP_TO: 'cancelOrdersUpTo',
TIME_BUFFER: new BigNumber(1000),
};

View File

@@ -27,7 +27,7 @@ export const exchangeDataEncoder = {
} else if (constants.MARKET_FILL_FN_NAMES.indexOf(fnName) !== -1) {
data = (exchangeInstance as any)[fnName].getABIEncodedTransactionData(
orders,
orders[0].takerAssetAmount,
orders.map(order => order.takerAssetAmount).reduce((prev, curr) => prev.plus(curr)),
orders.map(order => order.signature),
);
} else if (fnName === constants.MATCH_ORDERS) {

View File

@@ -1,13 +1,13 @@
import { SignedZeroExTransaction } from '@0x/types';
import { BigNumber } from '@0x/utils';
export interface TECApproval {
transactionHash: string;
transactionSignature: string;
transaction: SignedZeroExTransaction;
approvalExpirationTimeSeconds: BigNumber;
}
export interface SignedTECApproval extends TECApproval {
approvalSignature: string;
signature: string;
}
export enum TECSignatureType {