Update coordinator tests to comply with mixed EIP712 domains.

This commit is contained in:
Lawrence Forman
2019-03-15 16:45:28 -04:00
parent afaabb3673
commit 616907eff8
9 changed files with 113 additions and 174 deletions

View File

@@ -1,5 +1,13 @@
import { chaiSetup, constants, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils';
import {
addressUtils,
chaiSetup,
constants,
provider,
txDefaults,
web3Wrapper
} from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { transactionHashUtils } from '@0x/order-utils';
import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
@@ -11,6 +19,7 @@ const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
describe('Libs tests', () => {
let testLibs: TestLibsContract;
const exchangeAddress = addressUtils.generatePseudoRandomAddress();
before(async () => {
await blockchainLifecycle.startAsync();
@@ -19,7 +28,12 @@ describe('Libs tests', () => {
await blockchainLifecycle.revertAsync();
});
before(async () => {
testLibs = await TestLibsContract.deployFrom0xArtifactAsync(artifacts.TestLibs, provider, txDefaults);
testLibs = await TestLibsContract.deployFrom0xArtifactAsync(
artifacts.TestLibs,
provider,
txDefaults,
exchangeAddress,
);
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
@@ -31,12 +45,12 @@ describe('Libs tests', () => {
describe('getTransactionHash', () => {
it('should return the correct transaction hash', async () => {
const tx = {
verifyingContractAddress: testLibs.address,
verifyingContractAddress: exchangeAddress,
salt: new BigNumber(0),
signerAddress: constants.NULL_ADDRESS,
data: '0x1234',
};
const expectedTxHash = hashUtils.getTransactionHashHex(tx);
const expectedTxHash = transactionHashUtils.getTransactionHashHex(tx);
const txHash = await testLibs.publicGetTransactionHash.callAsync(tx);
expect(expectedTxHash).to.eq(txHash);
});
@@ -45,7 +59,7 @@ describe('Libs tests', () => {
describe('getApprovalHash', () => {
it('should return the correct approval hash', async () => {
const signedTx = {
verifyingContractAddress: testLibs.address,
verifyingContractAddress: exchangeAddress,
salt: new BigNumber(0),
signerAddress: constants.NULL_ADDRESS,
data: '0x1234',
@@ -55,12 +69,13 @@ describe('Libs tests', () => {
const txOrigin = constants.NULL_ADDRESS;
const approval = {
txOrigin,
transactionHash: hashUtils.getTransactionHashHex(signedTx),
transactionHash: transactionHashUtils.getTransactionHashHex(signedTx),
transactionSignature: signedTx.signature,
approvalExpirationTimeSeconds,
};
const expectedApprovalHash = hashUtils.getApprovalHashHex(
signedTx,
testLibs.address,
txOrigin,
approvalExpirationTimeSeconds,
);

View File

@@ -1,14 +1,17 @@
import {
addressUtils,
chaiSetup,
constants as devConstants,
expectContractCallFailedAsync,
getLatestBlockTimestampAsync,
provider,
TransactionFactory,
txDefaults,
web3Wrapper,
} from '@0x/contracts-test-utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { RevertReason, SignedOrder } from '@0x/types';
import { transactionHashUtils } from '@0x/order-utils';
import { RevertReason, SignatureType, SignedOrder } from '@0x/types';
import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
import * as ethUtil from 'ethereumjs-util';
@@ -17,10 +20,7 @@ import {
ApprovalFactory,
artifacts,
constants,
CoordinatorSignatureType,
CoordinatorTransactionFactory,
exchangeDataEncoder,
hashUtils,
TestMixinsContract,
} from '../src';
@@ -33,10 +33,12 @@ describe('Mixins tests', () => {
let approvalSignerAddress1: string;
let approvalSignerAddress2: string;
let mixins: TestMixinsContract;
let transactionFactory: CoordinatorTransactionFactory;
let transactionFactory: TransactionFactory;
let approvalFactory1: ApprovalFactory;
let approvalFactory2: ApprovalFactory;
let defaultOrder: SignedOrder;
const exchangeAddress = addressUtils.generatePseudoRandomAddress();
before(async () => {
await blockchainLifecycle.startAsync();
});
@@ -44,7 +46,12 @@ describe('Mixins tests', () => {
await blockchainLifecycle.revertAsync();
});
before(async () => {
mixins = await TestMixinsContract.deployFrom0xArtifactAsync(artifacts.TestMixins, provider, txDefaults);
mixins = await TestMixinsContract.deployFrom0xArtifactAsync(
artifacts.TestMixins,
provider,
txDefaults,
exchangeAddress,
);
const accounts = await web3Wrapper.getAvailableAddressesAsync();
[transactionSignerAddress, approvalSignerAddress1, approvalSignerAddress2] = accounts.slice(0, 3);
defaultOrder = {
@@ -67,7 +74,7 @@ describe('Mixins tests', () => {
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 CoordinatorTransactionFactory(transactionSignerPrivateKey, mixins.address);
transactionFactory = new TransactionFactory(transactionSignerPrivateKey, exchangeAddress);
approvalFactory1 = new ApprovalFactory(approvalSignerPrivateKey1, mixins.address);
approvalFactory2 = new ApprovalFactory(approvalSignerPrivateKey2, mixins.address);
});
@@ -81,47 +88,58 @@ describe('Mixins tests', () => {
describe('getSignerAddress', () => {
it('should return the correct address using the EthSign signature type', async () => {
const data = devConstants.NULL_BYTES;
const transaction = transactionFactory.newSignedCoordinatorTransaction(
const transaction = transactionFactory.newSignedTransaction(
data,
CoordinatorSignatureType.EthSign,
SignatureType.EthSign,
);
const transactionHash = hashUtils.getTransactionHashHex(transaction);
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
const signerAddress = await mixins.getSignerAddress.callAsync(transactionHash, transaction.signature);
expect(transaction.signerAddress).to.eq(signerAddress);
});
it('should return the correct address using the EIP712 signature type', async () => {
const data = devConstants.NULL_BYTES;
const transaction = transactionFactory.newSignedCoordinatorTransaction(
const transaction = transactionFactory.newSignedTransaction(
data,
CoordinatorSignatureType.EIP712,
SignatureType.EIP712,
);
const transactionHash = hashUtils.getTransactionHashHex(transaction);
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
const signerAddress = await mixins.getSignerAddress.callAsync(transactionHash, transaction.signature);
expect(transaction.signerAddress).to.eq(signerAddress);
});
it('should revert with with the Illegal signature type', async () => {
const data = devConstants.NULL_BYTES;
const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const illegalSignatureByte = ethUtil.toBuffer(CoordinatorSignatureType.Illegal).toString('hex');
const transaction = transactionFactory.newSignedTransaction(data);
const illegalSignatureByte = ethUtil.toBuffer(SignatureType.Illegal).toString('hex');
transaction.signature = `${transaction.signature.slice(
0,
transaction.signature.length - 2,
)}${illegalSignatureByte}`;
const transactionHash = hashUtils.getTransactionHashHex(transaction);
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expectContractCallFailedAsync(
mixins.getSignerAddress.callAsync(transactionHash, transaction.signature),
RevertReason.SignatureIllegal,
);
});
it('should revert with with the Invalid signature type', async () => {
const data = devConstants.NULL_BYTES;
const transaction = transactionFactory.newSignedTransaction(data);
const invalidSignatureByte = ethUtil.toBuffer(SignatureType.Invalid).toString('hex');
transaction.signature = `0x${invalidSignatureByte}`;
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expectContractCallFailedAsync(
mixins.getSignerAddress.callAsync(transactionHash, transaction.signature),
RevertReason.SignatureInvalid,
);
});
it("should revert with with a signature type that doesn't exist", async () => {
const data = devConstants.NULL_BYTES;
const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const invalidSignatureByte = '03';
const transaction = transactionFactory.newSignedTransaction(data);
const invalidSignatureByte = '04';
transaction.signature = `${transaction.signature.slice(
0,
transaction.signature.length - 2,
)}${invalidSignatureByte}`;
const transactionHash = hashUtils.getTransactionHashHex(transaction);
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
expectContractCallFailedAsync(
mixins.getSignerAddress.callAsync(transactionHash, transaction.signature),
RevertReason.SignatureUnsupported,
@@ -134,7 +152,7 @@ describe('Mixins tests', () => {
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.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
@@ -167,7 +185,7 @@ describe('Mixins tests', () => {
};
const orders = [order];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
@@ -196,7 +214,7 @@ describe('Mixins tests', () => {
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.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
@@ -220,7 +238,7 @@ describe('Mixins tests', () => {
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.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
@@ -249,7 +267,7 @@ describe('Mixins tests', () => {
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.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
@@ -273,7 +291,7 @@ describe('Mixins tests', () => {
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.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
@@ -309,7 +327,7 @@ describe('Mixins tests', () => {
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.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
@@ -344,7 +362,7 @@ describe('Mixins tests', () => {
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.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
@@ -387,7 +405,7 @@ describe('Mixins tests', () => {
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 = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
@@ -419,7 +437,7 @@ describe('Mixins tests', () => {
senderAddress: devConstants.NULL_ADDRESS,
}));
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
@@ -451,7 +469,7 @@ describe('Mixins tests', () => {
senderAddress: devConstants.NULL_ADDRESS,
}));
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
@@ -473,7 +491,7 @@ describe('Mixins tests', () => {
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 = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
@@ -502,7 +520,7 @@ describe('Mixins tests', () => {
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 = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval1 = approvalFactory1.newSignedApproval(
@@ -536,7 +554,7 @@ describe('Mixins tests', () => {
it(`Should be successful: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver1], approval_sig=[], expiration=[]`, async () => {
const orders = [defaultOrder, defaultOrder];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
await mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
orders,
@@ -558,7 +576,7 @@ describe('Mixins tests', () => {
it(`Should revert: function=${fnName} caller=approver1, senderAddress=[verifier,verifier], feeRecipient=[approver1,approver2], approval_sig=[approver2], expiration=[valid]`, async () => {
const orders = [defaultOrder, { ...defaultOrder, feeRecipientAddress: approvalSignerAddress2 }];
const data = exchangeDataEncoder.encodeOrdersToExchangeData(fnName, orders);
const transaction = transactionFactory.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval2 = approvalFactory2.newSignedApproval(
@@ -593,7 +611,7 @@ describe('Mixins tests', () => {
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.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
expectContractCallFailedAsync(
mixins.assertValidTransactionOrdersApproval.callAsync(
transaction,
@@ -621,7 +639,7 @@ describe('Mixins tests', () => {
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.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval = approvalFactory1.newSignedApproval(
@@ -657,7 +675,7 @@ describe('Mixins tests', () => {
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.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval1 = approvalFactory1.newSignedApproval(
@@ -698,7 +716,7 @@ describe('Mixins tests', () => {
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.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval2 = approvalFactory2.newSignedApproval(
@@ -734,7 +752,7 @@ describe('Mixins tests', () => {
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.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds1 = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approvalExpirationTimeSeconds2 = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
@@ -775,7 +793,7 @@ describe('Mixins tests', () => {
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.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).minus(constants.TIME_BUFFER);
const approval2 = approvalFactory2.newSignedApproval(
@@ -810,7 +828,7 @@ describe('Mixins tests', () => {
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.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
const currentTimestamp = await getLatestBlockTimestampAsync();
const approvalExpirationTimeSeconds = new BigNumber(currentTimestamp).plus(constants.TIME_BUFFER);
const approval1 = approvalFactory1.newSignedApproval(
@@ -848,7 +866,7 @@ describe('Mixins tests', () => {
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.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
@@ -861,7 +879,7 @@ describe('Mixins tests', () => {
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.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,
@@ -874,7 +892,7 @@ describe('Mixins tests', () => {
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.newSignedCoordinatorTransaction(data);
const transaction = transactionFactory.newSignedTransaction(data);
await mixins.assertValidCoordinatorApprovals.callAsync(
transaction,
transactionSignerAddress,

View File

@@ -1,35 +1,43 @@
import { SignedZeroExTransaction } from '@0x/types';
import { signingUtils } from '@0x/contracts-test-utils';
import { SignatureType, SignedZeroExTransaction } from '@0x/types';
import { BigNumber } from '@0x/utils';
import * as ethUtil from 'ethereumjs-util';
import { CoordinatorSignatureType, hashUtils, SignedCoordinatorApproval, signingUtils } from './index';
import { hashUtils, SignedCoordinatorApproval } from './index';
export class ApprovalFactory {
private readonly _privateKey: Buffer;
private readonly _verifyingContractAddress: string;
constructor(privateKey: Buffer, verifyingContractAddress: string) {
constructor(
privateKey: Buffer,
verifyingContractAddress: string) {
this._privateKey = privateKey;
this._verifyingContractAddress = verifyingContractAddress;
}
public newSignedApproval(
transaction: SignedZeroExTransaction,
txOrigin: string,
approvalExpirationTimeSeconds: BigNumber,
signatureType: CoordinatorSignatureType = CoordinatorSignatureType.EthSign,
signatureType: SignatureType = SignatureType.EthSign,
): SignedCoordinatorApproval {
const coordinatorTransaction = {
...transaction,
verifyingContractAddress: this._verifyingContractAddress,
};
const approvalHashBuff = hashUtils.getApprovalHashBuffer(
coordinatorTransaction,
transaction,
this._verifyingContractAddress,
txOrigin,
approvalExpirationTimeSeconds,
);
const signatureBuff = signingUtils.signMessage(approvalHashBuff, this._privateKey, signatureType);
const signatureBuff = signingUtils.signMessage(
approvalHashBuff,
this._privateKey,
signatureType,
);
const signedApproval = {
txOrigin,
transaction: coordinatorTransaction,
transaction: transaction,
approvalExpirationTimeSeconds,
signature: ethUtil.addHexPrefix(signatureBuff.toString('hex')),
};

View File

@@ -1,17 +1,6 @@
import { BigNumber } from '@0x/utils';
export const constants = {
COORDINATOR_DOMAIN_NAME: '0x Protocol Coordinator',
COORDINATOR_DOMAIN_VERSION: '1.0.0',
COORDINATOR_APPROVAL_SCHEMA: {
name: 'CoordinatorApproval',
parameters: [
{ name: 'txOrigin', type: 'address' },
{ name: 'transactionHash', type: 'bytes32' },
{ name: 'transactionSignature', type: 'bytes' },
{ name: 'approvalExpirationTimeSeconds', type: 'uint256' },
],
},
SINGLE_FILL_FN_NAMES: ['fillOrder', 'fillOrKillOrder', 'fillOrderNoThrow'],
BATCH_FILL_FN_NAMES: ['batchFillOrders', 'batchFillOrKillOrders', 'batchFillOrdersNoThrow'],
MARKET_FILL_FN_NAMES: ['marketBuyOrders', 'marketBuyOrdersNoThrow', 'marketSellOrders', 'marketSellOrdersNoThrow'],

View File

@@ -1,34 +0,0 @@
import { generatePseudoRandomSalt } from '@0x/order-utils';
import { SignedZeroExTransaction } from '@0x/types';
import * as ethUtil from 'ethereumjs-util';
import { CoordinatorSignatureType, hashUtils, signingUtils } from './index';
export class CoordinatorTransactionFactory {
private readonly _signerBuff: Buffer;
private readonly _verifyingContractAddress: string;
private readonly _privateKey: Buffer;
constructor(privateKey: Buffer, verifyingContractAddress: string) {
this._privateKey = privateKey;
this._verifyingContractAddress = verifyingContractAddress;
this._signerBuff = ethUtil.privateToAddress(this._privateKey);
}
public newSignedCoordinatorTransaction(
data: string,
signatureType: CoordinatorSignatureType = CoordinatorSignatureType.EthSign,
): SignedZeroExTransaction {
const transaction = {
verifyingContractAddress: this._verifyingContractAddress,
signerAddress: ethUtil.addHexPrefix(this._signerBuff.toString('hex')),
salt: generatePseudoRandomSalt(),
data,
};
const transactionHashBuff = hashUtils.getTransactionHashBuffer(transaction);
const signatureBuff = signingUtils.signMessage(transactionHashBuff, this._privateKey, signatureType);
const signedTransaction = {
...transaction,
signature: ethUtil.addHexPrefix(signatureBuff.toString('hex')),
};
return signedTransaction;
}
}

View File

@@ -1,23 +1,21 @@
import { eip712Utils } from '@0x/order-utils';
import { constants as orderUtilsConstants } from '@0x/order-utils/lib/src/constants';
import { constants, eip712Utils, transactionHashUtils } from '@0x/order-utils';
import { SignedZeroExTransaction, ZeroExTransaction } from '@0x/types';
import { BigNumber, signTypedDataUtils } from '@0x/utils';
import * as _ from 'lodash';
import { constants } from './index';
export const hashUtils = {
getApprovalHashBuffer(
transaction: SignedZeroExTransaction,
verifyingContractAddress: string,
txOrigin: string,
approvalExpirationTimeSeconds: BigNumber,
): Buffer {
const domain = {
name: constants.COORDINATOR_DOMAIN_NAME,
version: constants.COORDINATOR_DOMAIN_VERSION,
verifyingContractAddress: transaction.verifyingContractAddress,
verifyingContractAddress: verifyingContractAddress,
};
const transactionHash = hashUtils.getTransactionHashHex(transaction);
const transactionHash = transactionHashUtils.getTransactionHashHex(transaction);
const approval = {
txOrigin,
transactionHash,
@@ -37,34 +35,18 @@ export const hashUtils = {
},
getApprovalHashHex(
transaction: SignedZeroExTransaction,
verifyingContractAddress: string,
txOrigin: string,
approvalExpirationTimeSeconds: BigNumber,
): string {
const hashHex = `0x${hashUtils
.getApprovalHashBuffer(transaction, txOrigin, approvalExpirationTimeSeconds)
.getApprovalHashBuffer(
transaction,
verifyingContractAddress,
txOrigin,
approvalExpirationTimeSeconds,
)
.toString('hex')}`;
return hashHex;
},
getTransactionHashBuffer(transaction: ZeroExTransaction | SignedZeroExTransaction): Buffer {
const domain = {
name: constants.COORDINATOR_DOMAIN_NAME,
version: constants.COORDINATOR_DOMAIN_VERSION,
verifyingContractAddress: transaction.verifyingContractAddress,
};
const normalizedTransaction = _.mapValues(transaction, value => {
return !_.isString(value) ? value.toString() : value;
});
const typedData = eip712Utils.createTypedData(
orderUtilsConstants.EXCHANGE_ZEROEX_TRANSACTION_SCHEMA.name,
{ ZeroExTransaction: orderUtilsConstants.EXCHANGE_ZEROEX_TRANSACTION_SCHEMA.parameters },
normalizedTransaction,
domain,
);
const hashBuffer = signTypedDataUtils.generateTypedDataHash(typedData);
return hashBuffer;
},
getTransactionHashHex(transaction: ZeroExTransaction | SignedZeroExTransaction): string {
const hashHex = `0x${hashUtils.getTransactionHashBuffer(transaction).toString('hex')}`;
return hashHex;
},
};

View File

@@ -1,6 +1,4 @@
export { hashUtils } from './hash_utils';
export { signingUtils } from './signing_utils';
export { CoordinatorTransactionFactory } from './coordinator_transaction_factory';
export { ApprovalFactory } from './approval_factory';
export { constants } from './constants';
export { exchangeDataEncoder } from './exchange_data_encoder';

View File

@@ -1,30 +0,0 @@
import * as ethUtil from 'ethereumjs-util';
import { CoordinatorSignatureType } from './types';
export const signingUtils = {
signMessage(message: Buffer, privateKey: Buffer, signatureType: CoordinatorSignatureType): Buffer {
if (signatureType === CoordinatorSignatureType.EthSign) {
const prefixedMessage = ethUtil.hashPersonalMessage(message);
const ecSignature = ethUtil.ecsign(prefixedMessage, privateKey);
const signature = Buffer.concat([
ethUtil.toBuffer(ecSignature.v),
ecSignature.r,
ecSignature.s,
ethUtil.toBuffer(signatureType),
]);
return signature;
} else if (signatureType === CoordinatorSignatureType.EIP712) {
const ecSignature = ethUtil.ecsign(message, privateKey);
const signature = Buffer.concat([
ethUtil.toBuffer(ecSignature.v),
ecSignature.r,
ecSignature.s,
ethUtil.toBuffer(signatureType),
]);
return signature;
} else {
throw new Error(`${signatureType} is not a valid signature type`);
}
},
};

View File

@@ -10,10 +10,3 @@ export interface CoordinatorApproval {
export interface SignedCoordinatorApproval extends CoordinatorApproval {
signature: string;
}
export enum CoordinatorSignatureType {
Illegal,
EIP712,
EthSign,
NSignatureTypes,
}