Add more verification test cases

This commit is contained in:
Amir Bandeali 2019-02-19 18:07:32 -05:00
parent 3c649df3df
commit 2de9b862d8
4 changed files with 437 additions and 187 deletions

View File

@ -1,4 +1,3 @@
import { artifacts as exchangeArtifacts, IExchangeContract } from '@0x/contracts-exchange';
import {
chaiSetup,
constants as devConstants,
@ -18,6 +17,7 @@ import {
ApprovalFactory,
artifacts,
constants,
exchangeDataEncoder,
hashUtils,
TECSignatureType,
TECTransactionFactory,
@ -29,34 +29,7 @@ const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
const timeBuffer = new BigNumber(1000);
const encodeBatchOrderApproval = (fn: string, orders: SignedOrder[], exchangeInstance: IExchangeContract): string => {
let data;
if (constants.BATCH_FILL_FN_NAMES.indexOf(fn) !== -1) {
data = (exchangeInstance as any)[fn].getABIEncodedTransactionData(
orders,
orders.map(order => order.takerAssetAmount),
orders.map(order => order.signature),
);
} else if (constants.MARKET_FILL_FN_NAMES.indexOf(fn) !== -1) {
data = (exchangeInstance as any)[fn].getABIEncodedTransactionData(
orders,
orders[0].takerAssetAmount,
orders.map(order => order.signature),
);
} else if (fn === 'matchOrders') {
data = (exchangeInstance as any)[fn].getABIEncodedTransactionData(
orders[0],
orders[1],
orders[0].signature,
orders[1].signature,
);
} else {
throw new Error(`Error: ${fn} not a batch fill function`);
}
return data;
};
describe.only('Mixins tests', () => {
describe('Mixins tests', () => {
let transactionSignerAddress: string;
let approvalSignerAddress1: string;
let approvalSignerAddress2: string;
@ -65,7 +38,6 @@ describe.only('Mixins tests', () => {
let approvalFactory1: ApprovalFactory;
let approvalFactory2: ApprovalFactory;
let defaultOrder: SignedOrder;
let exchangeInterface: IExchangeContract;
before(async () => {
await blockchainLifecycle.startAsync();
});
@ -74,13 +46,8 @@ describe.only('Mixins tests', () => {
});
before(async () => {
mixins = await TestMixinsContract.deployFrom0xArtifactAsync(artifacts.TestMixins, provider, txDefaults);
exchangeInterface = await IExchangeContract.deployFrom0xArtifactAsync(
exchangeArtifacts.IExchange,
provider,
txDefaults,
);
const accounts = await web3Wrapper.getAvailableAddressesAsync();
[transactionSignerAddress, approvalSignerAddress1, approvalSignerAddress2] = accounts.slice(0, 2);
[transactionSignerAddress, approvalSignerAddress1, approvalSignerAddress2] = accounts.slice(0, 3);
defaultOrder = {
exchangeAddress: devConstants.NULL_ADDRESS,
makerAddress: devConstants.NULL_ADDRESS,
@ -157,24 +124,20 @@ describe.only('Mixins tests', () => {
});
describe('Single order approvals', () => {
for (const fn of constants.SINGLE_FILL_FN_NAMES) {
it(`Should be successful: function=${fn}, caller=tx_signer, senderAddress=verifier, approval_sig=approver1, expiration=valid`, async () => {
const data = (exchangeInterface as any)[fn].getABIEncodedTransactionData(
defaultOrder,
defaultOrder.takerAssetAmount,
defaultOrder.signature,
);
for (const fnName of constants.SINGLE_FILL_FN_NAMES) {
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1], expiration=[valid]`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const transactionHash = hashUtils.getTransactionHashHex(transaction);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await mixins.assertValidSingleOrderApproval.callAsync(
defaultOrder,
transactionHash,
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
approvalExpirationTimeSeconds,
approval.approvalSignature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
{ from: transactionSignerAddress },
);
await mixins.assertValidTECApprovals.callAsync(
@ -185,27 +148,23 @@ describe.only('Mixins tests', () => {
{ from: transactionSignerAddress },
);
});
it(`Should be successful: function=${fn}, caller=tx_signer, senderAddress=null, approval_sig=approver1, expiration=valid`, async () => {
it(`Should be successful: function=${fnName}, caller=tx_signer, senderAddress=[null], approval_sig=[approver1], expiration=[valid]`, async () => {
const order = {
...defaultOrder,
senderAddress: devConstants.NULL_ADDRESS,
};
const data = (exchangeInterface as any)[fn].getABIEncodedTransactionData(
order,
order.takerAssetAmount,
order.signature,
);
const orders = [order];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const transactionHash = hashUtils.getTransactionHashHex(transaction);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await mixins.assertValidSingleOrderApproval.callAsync(
order,
transactionHash,
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
approvalExpirationTimeSeconds,
approval.approvalSignature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
{ from: transactionSignerAddress },
);
await mixins.assertValidTECApprovals.callAsync(
@ -216,88 +175,65 @@ describe.only('Mixins tests', () => {
{ from: transactionSignerAddress },
);
});
it(`Should be successful: function=${fn}, caller=approver1, senderAddress=verifier, approval_sig=null, expiration=valid`, async () => {
const data = (exchangeInterface as any)[fn].getABIEncodedTransactionData(
defaultOrder,
defaultOrder.takerAssetAmount,
defaultOrder.signature,
);
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[], expiration=[]`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const transactionHash = hashUtils.getTransactionHashHex(transaction);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approvalSignature = devConstants.NULL_BYTES;
await mixins.assertValidSingleOrderApproval.callAsync(
defaultOrder,
transactionHash,
transaction.signature,
approvalExpirationTimeSeconds,
approvalSignature,
{ from: approvalSignerAddress1 },
);
await mixins.assertValidTECApprovals.callAsync(
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approvalSignature],
{ from: approvalSignerAddress1 },
);
});
it(`Should be successful: function=${fn}, caller=approver1, senderAddress=verifier, approval_sig=approver1, expiration=invalid`, async () => {
const data = (exchangeInterface as any)[fn].getABIEncodedTransactionData(
defaultOrder,
defaultOrder.takerAssetAmount,
defaultOrder.signature,
);
const transaction = transactionFactory.newSignedTECTransaction(data);
const transactionHash = hashUtils.getTransactionHashHex(transaction);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await mixins.assertValidSingleOrderApproval.callAsync(
defaultOrder,
transactionHash,
transaction.signature,
approvalExpirationTimeSeconds,
approval.approvalSignature,
{ from: approvalSignerAddress1 },
);
await mixins.assertValidTECApprovals.callAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
{ from: approvalSignerAddress1 },
);
});
it(`Should be successful: function=${fn}, caller=approver1, senderAddress=verifier, approval_sig=null, expiration=null`, async () => {
const data = (exchangeInterface as any)[fn].getABIEncodedTransactionData(
defaultOrder,
defaultOrder.takerAssetAmount,
defaultOrder.signature,
);
const transaction = transactionFactory.newSignedTECTransaction(data);
const transactionHash = hashUtils.getTransactionHashHex(transaction);
await mixins.assertValidSingleOrderApproval.callAsync(
defaultOrder,
transactionHash,
transaction.signature,
devConstants.ZERO_AMOUNT,
devConstants.NULL_BYTES,
[],
[],
{ from: approvalSignerAddress1 },
);
await mixins.assertValidTECApprovals.callAsync(transaction, transaction.signature, [], [], {
from: approvalSignerAddress1,
});
});
it(`Should revert: function=${fn}, caller=tx_signer, senderAddress=verifier, approval_sig=invalid, expiration=valid`, async () => {
const data = (exchangeInterface as any)[fn].getABIEncodedTransactionData(
defaultOrder,
defaultOrder.takerAssetAmount,
defaultOrder.signature,
);
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[approver1], expiration=[invalid]`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
{ from: approvalSignerAddress1 },
);
await mixins.assertValidTECApprovals.callAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
{ from: approvalSignerAddress1 },
);
});
it(`Should be successful: function=${fnName}, caller=approver1, senderAddress=[verifier], approval_sig=[], expiration=[]`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[],
[],
{ from: approvalSignerAddress1 },
);
await mixins.assertValidTECApprovals.callAsync(transaction, transaction.signature, [], [], {
from: approvalSignerAddress1,
});
});
it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[invalid], expiration=[valid]`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const transactionHash = hashUtils.getTransactionHashHex(transaction);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
@ -306,12 +242,12 @@ describe.only('Mixins tests', () => {
4,
)}FFFFFFFF${approval.approvalSignature.slice(12)}`;
expectContractCallFailedAsync(
mixins.assertValidSingleOrderApproval.callAsync(
defaultOrder,
transactionHash,
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
approvalExpirationTimeSeconds,
approvalSignature,
[approvalExpirationTimeSeconds],
[approvalSignature],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
@ -327,24 +263,20 @@ describe.only('Mixins tests', () => {
RevertReason.InvalidApprovalSignature,
);
});
it(`Should revert: function=${fn}, caller=tx_signer, senderAddress=verifier, approval_sig=approver1, expiration=invalid`, async () => {
const data = (exchangeInterface as any)[fn].getABIEncodedTransactionData(
defaultOrder,
defaultOrder.takerAssetAmount,
defaultOrder.signature,
);
it(`Should revert: function=${fnName}, caller=tx_signer, senderAddress=[verifier], approval_sig=[approver1], expiration=[invalid]`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const transactionHash = hashUtils.getTransactionHashHex(transaction);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(timeBuffer);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
expectContractCallFailedAsync(
mixins.assertValidSingleOrderApproval.callAsync(
defaultOrder,
transactionHash,
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
approvalExpirationTimeSeconds,
approval.approvalSignature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
{ from: transactionSignerAddress },
),
RevertReason.ApprovalExpired,
@ -360,21 +292,53 @@ describe.only('Mixins tests', () => {
RevertReason.ApprovalExpired,
);
});
it(`Should revert: function=${fnName}, caller=approver2, senderAddress=[verifier], approval_sig=[approver1], expiration=[valid]`, async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
{ from: approvalSignerAddress2 },
),
RevertReason.InvalidSender,
);
expectContractCallFailedAsync(
mixins.assertValidTECApprovals.callAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
{ from: approvalSignerAddress2 },
),
RevertReason.InvalidSender,
);
});
}
});
describe('Batch order approvals', () => {
for (const fn of [...constants.BATCH_FILL_FN_NAMES, ...constants.MARKET_FILL_FN_NAMES, 'matchOrders']) {
it(`Should be successful: function=${fn} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => {
for (const fnName of [
...constants.BATCH_FILL_FN_NAMES,
...constants.MARKET_FILL_FN_NAMES,
constants.MATCH_ORDERS,
]) {
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => {
const orders = [defaultOrder, defaultOrder];
const data = encodeBatchOrderApproval(fn, orders, exchangeInterface);
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const transactionHash = hashUtils.getTransactionHashHex(transaction);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await mixins.assertValidBatchOrderApproval.callAsync(
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionHash,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
@ -388,20 +352,19 @@ describe.only('Mixins tests', () => {
{ from: transactionSignerAddress },
);
});
it(`Should be successful: function=${fn} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => {
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => {
const orders = [defaultOrder, defaultOrder].map(order => ({
...order,
senderAddress: devConstants.NULL_ADDRESS,
}));
const data = encodeBatchOrderApproval(fn, orders, exchangeInterface);
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const transactionHash = hashUtils.getTransactionHashHex(transaction);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await mixins.assertValidBatchOrderApproval.callAsync(
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionHash,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
@ -415,17 +378,16 @@ describe.only('Mixins tests', () => {
{ from: transactionSignerAddress },
);
});
it(`Should be successful: function=${fn} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[], expiration=[]`, async () => {
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[null,null], feeRecipient=[approver1,approver1], approval_sig=[], expiration=[]`, async () => {
const orders = [defaultOrder, defaultOrder].map(order => ({
...order,
senderAddress: devConstants.NULL_ADDRESS,
}));
const data = encodeBatchOrderApproval(fn, orders, exchangeInterface);
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const transactionHash = hashUtils.getTransactionHashHex(transaction);
await mixins.assertValidBatchOrderApproval.callAsync(
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionHash,
transaction.signature,
[],
[],
@ -435,17 +397,16 @@ describe.only('Mixins tests', () => {
from: transactionSignerAddress,
});
});
it(`Should be successful: function=${fn} caller=tx_signer, senderAddress=[verifier,null], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => {
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,null], feeRecipient=[approver1,approver1], approval_sig=[approver1], expiration=[valid]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, senderAddress: devConstants.NULL_ADDRESS }];
const data = encodeBatchOrderApproval(fn, orders, exchangeInterface);
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const transactionHash = hashUtils.getTransactionHashHex(transaction);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await mixins.assertValidBatchOrderApproval.callAsync(
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionHash,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval.approvalSignature],
@ -459,18 +420,17 @@ describe.only('Mixins tests', () => {
{ from: transactionSignerAddress },
);
});
it(`Should be successful: function=${fn} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver1,approver2], expiration=[valid,valid]`, async () => {
it(`Should be successful: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver1,approver2], expiration=[valid,valid]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = encodeBatchOrderApproval(fn, orders, exchangeInterface);
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const transactionHash = hashUtils.getTransactionHashHex(transaction);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approval1 = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await mixins.assertValidBatchOrderApproval.callAsync(
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionHash,
transaction.signature,
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
[approval1.approvalSignature, approval2.approvalSignature],
@ -484,14 +444,13 @@ describe.only('Mixins tests', () => {
{ from: transactionSignerAddress },
);
});
it(`Should be successful: function=${fn} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[], expiration=[]`, async () => {
it(`Should be successful: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[], expiration=[]`, async () => {
const orders = [defaultOrder, defaultOrder];
const data = encodeBatchOrderApproval(fn, orders, exchangeInterface);
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const transactionHash = hashUtils.getTransactionHashHex(transaction);
await mixins.assertValidBatchOrderApproval.callAsync(
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionHash,
transaction.signature,
[],
[],
@ -501,17 +460,16 @@ describe.only('Mixins tests', () => {
from: approvalSignerAddress1,
});
});
it(`Should be successful: function=${fn} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver2], expiration=[valid]`, async () => {
it(`Should be successful: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver2], expiration=[valid]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = encodeBatchOrderApproval(fn, orders, exchangeInterface);
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const transactionHash = hashUtils.getTransactionHashHex(transaction);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds);
await mixins.assertValidBatchOrderApproval.callAsync(
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transactionHash,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval2.approvalSignature],
@ -525,7 +483,243 @@ describe.only('Mixins tests', () => {
{ from: approvalSignerAddress1 },
);
});
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[], expiration=[]`, async () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[],
[],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
);
expectContractCallFailedAsync(
mixins.assertValidTECApprovals.callAsync(transaction, transaction.signature, [], [], {
from: transactionSignerAddress,
}),
RevertReason.InvalidApprovalSignature,
);
});
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[invalid], expiration=[valid]`, async () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approval = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
const approvalSignature = `${approval.approvalSignature.slice(
0,
4,
)}FFFFFFFF${approval.approvalSignature.slice(12)}`;
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approvalSignature],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
);
expectContractCallFailedAsync(
mixins.assertValidTECApprovals.callAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approvalSignature],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
);
});
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid,invalid], expiration=[valid,valid]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approval1 = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds);
const approvalSignature2 = `${approval2.approvalSignature.slice(
0,
4,
)}FFFFFFFF${approval2.approvalSignature.slice(12)}`;
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
[approval1.approvalSignature, approvalSignature2],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
);
expectContractCallFailedAsync(
mixins.assertValidTECApprovals.callAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds, approvalExpirationTimeSeconds],
[approval1.approvalSignature, approvalSignature2],
{ from: transactionSignerAddress },
),
RevertReason.InvalidApprovalSignature,
);
});
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[invalid], expiration=[valid]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds);
const approvalSignature2 = `${approval2.approvalSignature.slice(
0,
4,
)}FFFFFFFF${approval2.approvalSignature.slice(12)}`;
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approvalSignature2],
{ from: approvalSignerAddress1 },
),
RevertReason.InvalidApprovalSignature,
);
expectContractCallFailedAsync(
mixins.assertValidTECApprovals.callAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approvalSignature2],
{ from: approvalSignerAddress1 },
),
RevertReason.InvalidApprovalSignature,
);
});
it(`Should revert: function=${fnName} caller=tx_signer, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid,valid], expiration=[valid,invalid]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
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 approval1 = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds1);
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds2);
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds1, approvalExpirationTimeSeconds2],
[approval1.approvalSignature, approval2.approvalSignature],
{ from: transactionSignerAddress },
),
RevertReason.ApprovalExpired,
);
expectContractCallFailedAsync(
mixins.assertValidTECApprovals.callAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds1, approvalExpirationTimeSeconds2],
[approval1.approvalSignature, approval2.approvalSignature],
{ from: transactionSignerAddress },
),
RevertReason.ApprovalExpired,
);
});
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver2], approval_sig=[valid], expiration=[invalid]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(timeBuffer);
const approval2 = approvalFactory2.newSignedApproval(transaction, approvalExpirationTimeSeconds);
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval2.approvalSignature],
{ from: approvalSignerAddress1 },
),
RevertReason.ApprovalExpired,
);
expectContractCallFailedAsync(
mixins.assertValidTECApprovals.callAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval2.approvalSignature],
{ from: approvalSignerAddress1 },
),
RevertReason.ApprovalExpired,
);
});
it(`Should revert: function=${fnName} caller=approver2, senderAddress=[verifier,verifier], feeRecipient=[approver1, approver1], approval_sig=[valid], expiration=[valid]`, async () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(timeBuffer);
const approval1 = approvalFactory1.newSignedApproval(transaction, approvalExpirationTimeSeconds);
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval1.approvalSignature],
{ from: approvalSignerAddress2 },
),
RevertReason.InvalidSender,
);
expectContractCallFailedAsync(
mixins.assertValidTECApprovals.callAsync(
transaction,
transaction.signature,
[approvalExpirationTimeSeconds],
[approval1.approvalSignature],
{ from: approvalSignerAddress2 },
),
RevertReason.InvalidSender,
);
});
}
});
describe('assertValidTECApprovals', () => {});
describe('cancels', () => {
it('should allow the tx signer to call `cancelOrders` without approval', async () => {
const orders = [defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDERS, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
await mixins.assertValidTECApprovals.callAsync(transaction, transaction.signature, [], [], {
from: transactionSignerAddress,
});
});
it('should allow the tx signer to call `batchCancelOrders` without approval', async () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.BATCH_CANCEL_ORDERS, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
await mixins.assertValidTECApprovals.callAsync(transaction, transaction.signature, [], [], {
from: transactionSignerAddress,
});
});
it('should allow the tx signer to call `cancelOrdersUpTo` without approval', async () => {
const orders: SignedOrder[] = [];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(constants.CANCEL_ORDERS_UP_TO, orders);
const transaction = transactionFactory.newSignedTECTransaction(data);
await mixins.assertValidTECApprovals.callAsync(transaction, transaction.signature, [], [], {
from: transactionSignerAddress,
});
});
});
});

View File

@ -12,4 +12,8 @@ export const constants = {
SINGLE_FILL_FN_NAMES: ['fillOrder', 'fillOrKillOrder', 'fillOrderNoThrow'],
BATCH_FILL_FN_NAMES: ['batchFillOrders', 'batchFillOrKillOrders', 'batchFillOrdersNoThrow'],
MARKET_FILL_FN_NAMES: ['marketBuyOrders', 'marketBuyOrdersNoThrow', 'marketSellOrders', 'marketSellOrdersNoThrow'],
MATCH_ORDERS: 'matchOrders',
CANCEL_ORDERS: 'cancelOrders',
BATCH_CANCEL_ORDERS: 'batchCancelOrders',
CANCEL_ORDERS_UP_TO: 'cancelOrdersUpTo',
};

View File

@ -0,0 +1,51 @@
import { artifacts, IExchangeContract } from '@0x/contracts-exchange';
import { constants as devConstants, provider } from '@0x/contracts-test-utils';
import { SignedOrder } from '@0x/types';
import { constants } from './index';
export const exchangeDataEncoder = {
encodeOrdersToExchangeData(fnName: string, orders: SignedOrder[]): string {
const exchangeInstance = new IExchangeContract(
artifacts.IExchange.compilerOutput.abi,
devConstants.NULL_ADDRESS,
provider,
);
let data;
if (constants.SINGLE_FILL_FN_NAMES.indexOf(fnName) !== -1) {
data = (exchangeInstance as any)[fnName].getABIEncodedTransactionData(
orders[0],
orders[0].takerAssetAmount,
orders[0].signature,
);
} else if (constants.BATCH_FILL_FN_NAMES.indexOf(fnName) !== -1) {
data = (exchangeInstance as any)[fnName].getABIEncodedTransactionData(
orders,
orders.map(order => order.takerAssetAmount),
orders.map(order => order.signature),
);
} else if (constants.MARKET_FILL_FN_NAMES.indexOf(fnName) !== -1) {
data = (exchangeInstance as any)[fnName].getABIEncodedTransactionData(
orders,
orders[0].takerAssetAmount,
orders.map(order => order.signature),
);
} else if (fnName === constants.MATCH_ORDERS) {
data = exchangeInstance.matchOrders.getABIEncodedTransactionData(
orders[0],
orders[1],
orders[0].signature,
orders[1].signature,
);
} else if (fnName === constants.CANCEL_ORDERS) {
data = exchangeInstance.cancelOrder.getABIEncodedTransactionData(orders[0]);
} else if (fnName === constants.BATCH_CANCEL_ORDERS) {
data = exchangeInstance.batchCancelOrders.getABIEncodedTransactionData(orders);
} else if (fnName === constants.CANCEL_ORDERS_UP_TO) {
data = exchangeInstance.cancelOrdersUpTo.getABIEncodedTransactionData(devConstants.ZERO_AMOUNT);
} else {
throw new Error(`Error: ${fnName} not a supported function`);
}
return data;
},
};

View File

@ -3,4 +3,5 @@ export { signingUtils } from './signing_utils';
export { TECTransactionFactory } from './tec_transaction_factory';
export { ApprovalFactory } from './approval_factory';
export { constants } from './constants';
export { exchangeDataEncoder } from './exchange_data_encoder';
export * from './types';