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,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,
}