@0x/contracts-exchange: Add isValidHashSignature() back.

`@0x/contracts-exchange`: Remove references to removed signature types and associated functions.
This commit is contained in:
Lawrence Forman
2019-06-25 20:27:38 -04:00
committed by Amir Bandeali
parent 7f88e8ad6e
commit 7a0dc7a364
10 changed files with 162 additions and 198 deletions

View File

@@ -79,6 +79,46 @@ contract MixinSignatureValidator is
); );
} }
/// @dev Verifies that a hash has been signed by the given signer.
/// @param hash Any 32-byte hash.
/// @param signerAddress Address that should have signed the given hash.
/// @param signature Proof that the hash has been signed by signer.
/// @return isValid `true` if the signature is valid for the given hash and signer.
function isValidHashSignature(
bytes32 hash,
address signerAddress,
bytes memory signature
)
public
view
returns (bool isValid)
{
SignatureType signatureType = _readValidSignatureType(
hash,
signerAddress,
signature
);
// Only hash-compatible signature types can be handled by this
// function.
if (
signatureType == SignatureType.Validator ||
signatureType == SignatureType.EIP1271Wallet
) {
_rrevert(SignatureError(
SignatureErrorCodes.INAPPROPRIATE_SIGNATURE_TYPE,
hash,
signerAddress,
signature
));
}
return _validateHashSignatureTypes(
signatureType,
hash,
signerAddress,
signature
);
}
/// @dev Verifies that a signature for an order is valid. /// @dev Verifies that a signature for an order is valid.
/// @param order The order. /// @param order The order.
/// @param signerAddress Address that should have signed the given order. /// @param signerAddress Address that should have signed the given order.

View File

@@ -59,15 +59,19 @@ contract ISignatureValidator {
) )
external; external;
/// @dev Approves/unnapproves an OrderValidator contract to verify signatures on signer's behalf /// @dev Verifies that a hash has been signed by the given signer.
/// using the `OrderValidator` signature type. /// @param hash Any 32-byte hash.
/// @param validatorAddress Address of Validator contract. /// @param signerAddress Address that should have signed the given hash.
/// @param approval Approval or disapproval of Validator contract. /// @param signature Proof that the hash has been signed by signer.
function setOrderValidatorApproval( /// @return isValid `true` if the signature is valid for the given hash and signer.
address validatorAddress, function isValidHashSignature(
bool approval bytes32 hash,
address signerAddress,
bytes memory signature
) )
external; public
view
returns (bool isValid);
/// @dev Verifies that a signature for an order is valid. /// @dev Verifies that a signature for an order is valid.
/// @param order The order. /// @param order The order.
@@ -113,7 +117,13 @@ contract ISignatureValidator {
pure pure
returns (bool needsRegularValidation); returns (bool needsRegularValidation);
// Defined in MixinSignatureValidator /// @dev Verifies that an order, with provided order hash, has been signed
/// by the given signer.
/// @param order The order.
/// @param orderHash The hash of the order.
/// @param signerAddress Address that should have signed the.Signat given hash.
/// @param signature Proof that the hash has been signed by signer.
/// @return isValid True if the signature is valid for the given order and signer.
function _isValidOrderWithHashSignature( function _isValidOrderWithHashSignature(
LibOrder.Order memory order, LibOrder.Order memory order,
bytes32 orderHash, bytes32 orderHash,
@@ -124,7 +134,13 @@ contract ISignatureValidator {
view view
returns (bool isValid); returns (bool isValid);
// Defined in MixinSignatureValidator /// @dev Verifies that a transaction, with provided order hash, has been signed
/// by the given signer.
/// @param transaction The transaction.
/// @param transactionHash The hash of the transaction.
/// @param signerAddress Address that should have signed the.Signat given hash.
/// @param signature Proof that the hash has been signed by signer.
/// @return isValid True if the signature is valid for the given transaction and signer.
function _isValidTransactionWithHashSignature( function _isValidTransactionWithHashSignature(
LibZeroExTransaction.ZeroExTransaction memory transaction, LibZeroExTransaction.ZeroExTransaction memory transaction,
bytes32 transactionHash, bytes32 transactionHash,

View File

@@ -52,7 +52,6 @@ contract ReentrantERC20Token is
CANCEL_ORDERS_UP_TO, CANCEL_ORDERS_UP_TO,
PRE_SIGN, PRE_SIGN,
SET_SIGNATURE_VALIDATOR_APPROVAL, SET_SIGNATURE_VALIDATOR_APPROVAL,
SET_ORDER_VALIDATOR_APPROVAL,
NONE NONE
} }
@@ -174,12 +173,6 @@ contract ReentrantERC20Token is
_getRandomAddress(), _getRandomAddress(),
false false
); );
} else if (currentFunctionId == uint8(ExchangeFunction.SET_ORDER_VALIDATOR_APPROVAL)) {
callData = abi.encodeWithSelector(
exchange.setOrderValidatorApproval.selector,
_getRandomAddress(),
false
);
} else { } else {
return true; return true;
} }

View File

@@ -49,6 +49,7 @@ import {
ReentrantERC20TokenContract, ReentrantERC20TokenContract,
TestValidatorWalletContract, TestValidatorWalletContract,
ValidatorWalletAction, ValidatorWalletAction,
ValidatorWalletDataType,
} from '../src'; } from '../src';
chaiSetup.configure(); chaiSetup.configure();
@@ -265,8 +266,8 @@ describe('Exchange core', () => {
validatorWallet.address, validatorWallet.address,
constants.INITIAL_ERC20_BALANCE, constants.INITIAL_ERC20_BALANCE,
); );
// Approve the order validator. // Approve the validator.
await exchange.setOrderValidatorApproval.awaitTransactionSuccessAsync(validatorWallet.address, true, { await exchange.setSignatureValidatorApproval.awaitTransactionSuccessAsync(validatorWallet.address, true, {
from: makerAddress, from: makerAddress,
}); });
signedOrder = await orderFactory.newSignedOrderAsync({ signedOrder = await orderFactory.newSignedOrderAsync({
@@ -275,26 +276,28 @@ describe('Exchange core', () => {
}); });
}); });
it('should revert if `OrderValidator` signature type rejects during a second fill', async () => { it('should revert if `Validator` signature type rejects during a second fill', async () => {
const signature = Buffer.concat([ const signature = Buffer.concat([
ethUtil.toBuffer(validatorWallet.address), ethUtil.toBuffer(validatorWallet.address),
ethUtil.toBuffer([SignatureType.OrderValidator]), ethUtil.toBuffer([SignatureType.Validator]),
]); ]);
signedOrder.signature = ethUtil.bufferToHex(signature); signedOrder.signature = ethUtil.bufferToHex(signature);
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
// Allow the signature check for the first fill. // Allow the signature check for the first fill.
await validatorWallet.setValidateAction.awaitTransactionSuccessAsync( await validatorWallet.prepare.awaitTransactionSuccessAsync(
orderHashHex, orderHashHex,
ValidatorWalletDataType.Order,
ValidatorWalletAction.Accept, ValidatorWalletAction.Accept,
makerAddress, constants.NULL_BYTES,
); );
const fillAmount = signedOrder.takerAssetAmount.div(10); const fillAmount = signedOrder.takerAssetAmount.div(10);
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount: fillAmount }); await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount: fillAmount });
// Reject the signature check for the second fill. // Reject the signature check for the second fill.
await validatorWallet.setValidateAction.awaitTransactionSuccessAsync( await validatorWallet.prepare.awaitTransactionSuccessAsync(
orderHashHex, orderHashHex,
ValidatorWalletDataType.Order,
ValidatorWalletAction.Reject, ValidatorWalletAction.Reject,
makerAddress, constants.NULL_BYTES,
); );
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
takerAssetFillAmount: fillAmount, takerAssetFillAmount: fillAmount,
@@ -308,24 +311,26 @@ describe('Exchange core', () => {
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
it('should revert if `OrderWallet` signature type rejects during a second fill', async () => { it('should revert if `Wallet` signature type rejects during a second fill', async () => {
const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.OrderWallet])]); const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.Wallet])]);
signedOrder.makerAddress = validatorWallet.address; signedOrder.makerAddress = validatorWallet.address;
signedOrder.signature = ethUtil.bufferToHex(signature); signedOrder.signature = ethUtil.bufferToHex(signature);
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
// Allow the signature check for the first fill. // Allow the signature check for the first fill.
await validatorWallet.setValidateAction.awaitTransactionSuccessAsync( await validatorWallet.prepare.awaitTransactionSuccessAsync(
orderHashHex, orderHashHex,
ValidatorWalletDataType.Order,
ValidatorWalletAction.Accept, ValidatorWalletAction.Accept,
makerAddress, constants.NULL_BYTES,
); );
const fillAmount = signedOrder.takerAssetAmount.div(10); const fillAmount = signedOrder.takerAssetAmount.div(10);
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount: fillAmount }); await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount: fillAmount });
// Reject the signature check for the second fill. // Reject the signature check for the second fill.
await validatorWallet.setValidateAction.awaitTransactionSuccessAsync( await validatorWallet.prepare.awaitTransactionSuccessAsync(
orderHashHex, orderHashHex,
ValidatorWalletDataType.Order,
ValidatorWalletAction.Reject, ValidatorWalletAction.Reject,
makerAddress, constants.NULL_BYTES,
); );
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
takerAssetFillAmount: fillAmount, takerAssetFillAmount: fillAmount,
@@ -339,24 +344,26 @@ describe('Exchange core', () => {
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
it('should revert if `EIP1271OrderWallet` signature type rejects during a second fill', async () => { it('should revert if `EIP1271Wallet` signature type rejects during a second fill', async () => {
const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.EIP1271OrderWallet])]); const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.EIP1271Wallet])]);
signedOrder.makerAddress = validatorWallet.address; signedOrder.makerAddress = validatorWallet.address;
signedOrder.signature = ethUtil.bufferToHex(signature); signedOrder.signature = ethUtil.bufferToHex(signature);
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
// Allow the signature check for the first fill. // Allow the signature check for the first fill.
await validatorWallet.setValidateAction.awaitTransactionSuccessAsync( await validatorWallet.prepare.awaitTransactionSuccessAsync(
orderHashHex, orderHashHex,
ValidatorWalletDataType.Order,
ValidatorWalletAction.Accept, ValidatorWalletAction.Accept,
signedOrder.makerAddress, constants.NULL_BYTES,
); );
const fillAmount = signedOrder.takerAssetAmount.div(10); const fillAmount = signedOrder.takerAssetAmount.div(10);
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount: fillAmount }); await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount: fillAmount });
// Reject the signature check for the second fill. // Reject the signature check for the second fill.
await validatorWallet.setValidateAction.awaitTransactionSuccessAsync( await validatorWallet.prepare.awaitTransactionSuccessAsync(
orderHashHex, orderHashHex,
ValidatorWalletDataType.Order,
ValidatorWalletAction.Reject, ValidatorWalletAction.Reject,
signedOrder.makerAddress, constants.NULL_BYTES,
); );
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
takerAssetFillAmount: fillAmount, takerAssetFillAmount: fillAmount,

View File

@@ -80,7 +80,6 @@ describe('LibExchangeRichErrorDecoder', () => {
const errorData = generateRandomBytes(ERROR_DATA_LENGTH); const errorData = generateRandomBytes(ERROR_DATA_LENGTH);
createDecodeTest(ExchangeRevertErrors.SignatureError, [errorCode, orderHash, signer, signature]); createDecodeTest(ExchangeRevertErrors.SignatureError, [errorCode, orderHash, signer, signature]);
createDecodeTest(ExchangeRevertErrors.SignatureValidatorNotApprovedError, [signer, validator]); createDecodeTest(ExchangeRevertErrors.SignatureValidatorNotApprovedError, [signer, validator]);
createDecodeTest(ExchangeRevertErrors.SignatureOrderValidatorNotApprovedError, [signer, validator]);
createDecodeTest(ExchangeRevertErrors.SignatureValidatorError, [ createDecodeTest(ExchangeRevertErrors.SignatureValidatorError, [
orderHash, orderHash,
signer, signer,
@@ -89,14 +88,6 @@ describe('LibExchangeRichErrorDecoder', () => {
errorData, errorData,
]); ]);
createDecodeTest(ExchangeRevertErrors.SignatureWalletError, [orderHash, signer, signature, errorData]); createDecodeTest(ExchangeRevertErrors.SignatureWalletError, [orderHash, signer, signature, errorData]);
createDecodeTest(ExchangeRevertErrors.SignatureOrderValidatorError, [
orderHash,
signer,
validator,
signature,
errorData,
]);
createDecodeTest(ExchangeRevertErrors.SignatureOrderWalletError, [orderHash, signer, signature, errorData]);
})(); })();
(() => { (() => {

View File

@@ -24,14 +24,14 @@ import {
TestValidatorWalletContract, TestValidatorWalletContract,
} from '../src'; } from '../src';
import { ValidatorWalletAction } from './utils'; import { ValidatorWalletAction, ValidatorWalletDataType } from './utils';
chaiSetup.configure(); chaiSetup.configure();
const expect = chai.expect; const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
// tslint:disable:no-unnecessary-type-assertion // tslint:disable:no-unnecessary-type-assertion
describe('MixinSignatureValidator', () => { describe.only('MixinSignatureValidator', () => {
const SIGNATURE_LENGTH = 65; const SIGNATURE_LENGTH = 65;
let chainId: number; let chainId: number;
let signedOrder: SignedOrder; let signedOrder: SignedOrder;
@@ -73,17 +73,11 @@ describe('MixinSignatureValidator', () => {
// Approve the validator for both signers. // Approve the validator for both signers.
await Promise.all( await Promise.all(
[signerAddress, notSignerAddress].map(async (addr: string) => { [signerAddress, notSignerAddress].map(async (addr: string) => {
const tx1 = signatureValidator.setSignatureValidatorApproval.awaitTransactionSuccessAsync( return signatureValidator.setSignatureValidatorApproval.awaitTransactionSuccessAsync(
validatorWallet.address, validatorWallet.address,
true, true,
{ from: addr }, { from: addr },
); );
const tx2 = signatureValidator.setOrderValidatorApproval.awaitTransactionSuccessAsync(
validatorWallet.address,
true,
{ from: addr },
);
return Promise.all([tx1, tx2]);
}), }),
); );
@@ -244,7 +238,7 @@ describe('MixinSignatureValidator', () => {
signedOrder, signedOrder,
validatorWallet.address, validatorWallet.address,
signatureHex, signatureHex,
ValidatorWalletAction.ValidateSignature, ValidatorWalletAction.MatchSignatureHash,
); );
expect(isValidSignature).to.be.true(); expect(isValidSignature).to.be.true();
}); });
@@ -258,7 +252,7 @@ describe('MixinSignatureValidator', () => {
signedOrder, signedOrder,
notSignerAddress, notSignerAddress,
signatureHex, signatureHex,
ValidatorWalletAction.ValidateSignature, ValidatorWalletAction.MatchSignatureHash,
); );
expect(isValidSignature).to.be.false(); expect(isValidSignature).to.be.false();
}); });
@@ -314,7 +308,7 @@ describe('MixinSignatureValidator', () => {
signedOrder, signedOrder,
signerAddress, signerAddress,
signatureHex, signatureHex,
ValidatorWalletAction.ValidateSignature, ValidatorWalletAction.MatchSignatureHash,
); );
expect(isValidSignature).to.be.true(); expect(isValidSignature).to.be.true();
}); });
@@ -329,7 +323,7 @@ describe('MixinSignatureValidator', () => {
signedOrder, signedOrder,
signerAddress, signerAddress,
ethUtil.bufferToHex(signature), ethUtil.bufferToHex(signature),
ValidatorWalletAction.ValidateSignature, ValidatorWalletAction.MatchSignatureHash,
); );
expect(isValidSignature).to.be.false(); expect(isValidSignature).to.be.false();
}); });
@@ -390,7 +384,7 @@ describe('MixinSignatureValidator', () => {
signedOrder, signedOrder,
signerAddress, signerAddress,
signatureHex, signatureHex,
ValidatorWalletAction.ValidateSignature, ValidatorWalletAction.MatchSignatureHash,
); );
const expectedError = new ExchangeRevertErrors.SignatureValidatorNotApprovedError( const expectedError = new ExchangeRevertErrors.SignatureValidatorNotApprovedError(
signerAddress, signerAddress,
@@ -408,7 +402,7 @@ describe('MixinSignatureValidator', () => {
signedOrder, signedOrder,
validatorWallet.address, validatorWallet.address,
signatureHex, signatureHex,
ValidatorWalletAction.ValidateSignature, ValidatorWalletAction.MatchSignatureHash,
); );
expect(isValidSignature).to.be.true(); expect(isValidSignature).to.be.true();
}); });
@@ -491,16 +485,18 @@ describe('MixinSignatureValidator', () => {
describe('isValidHashSignature', () => { describe('isValidHashSignature', () => {
const validateCallAsync = async ( const validateCallAsync = async (
order: SignedOrder, order: SignedOrder,
validSigner: string, expectedSignatureHex: string,
signatureHex: string, signatureHex: string,
validatorAction?: ValidatorWalletAction, validatorAction?: ValidatorWalletAction,
) => { ) => {
const orderHashHex = orderHashUtils.getOrderHashHex(order); const orderHashHex = orderHashUtils.getOrderHashHex(order);
const signatureHashHex = ethUtil.bufferToHex(ethUtil.sha3(expectedSignatureHex));
if (validatorAction !== undefined) { if (validatorAction !== undefined) {
await validatorWallet.setValidateAction.awaitTransactionSuccessAsync( await validatorWallet.prepare.awaitTransactionSuccessAsync(
orderHashHex, orderHashHex,
ValidatorWalletDataType.None,
validatorAction, validatorAction,
validSigner, signatureHashHex,
); );
} }
return signatureValidator.isValidHashSignature.callAsync(orderHashHex, order.makerAddress, signatureHex); return signatureValidator.isValidHashSignature.callAsync(orderHashHex, order.makerAddress, signatureHex);
@@ -510,8 +506,8 @@ describe('MixinSignatureValidator', () => {
signedOrder = await orderFactory.newSignedOrderAsync(); signedOrder = await orderFactory.newSignedOrderAsync();
}); });
it('should revert when SignatureType=OrderValidator', async () => { it('should revert when SignatureType=Validator', async () => {
const inappropriateSignatureHex = `0x${Buffer.from([SignatureType.OrderValidator]).toString('hex')}`; const inappropriateSignatureHex = `0x${Buffer.from([SignatureType.Validator]).toString('hex')}`;
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
const expectedError = new ExchangeRevertErrors.SignatureError( const expectedError = new ExchangeRevertErrors.SignatureError(
ExchangeRevertErrors.SignatureErrorCode.InappropriateSignatureType, ExchangeRevertErrors.SignatureErrorCode.InappropriateSignatureType,
@@ -570,16 +566,18 @@ describe('MixinSignatureValidator', () => {
describe('isValidOrderSignature', () => { describe('isValidOrderSignature', () => {
const validateCallAsync = async ( const validateCallAsync = async (
order: SignedOrder, order: SignedOrder,
validSigner: string, expectedSignatureHex: string,
signatureHex: string, signatureHex: string,
validatorAction?: ValidatorWalletAction, validatorAction?: ValidatorWalletAction,
) => { ) => {
const orderHashHex = orderHashUtils.getOrderHashHex(order); const orderHashHex = orderHashUtils.getOrderHashHex(order);
const signatureHashHex = ethUtil.bufferToHex(ethUtil.sha3(expectedSignatureHex));
if (validatorAction !== undefined) { if (validatorAction !== undefined) {
await validatorWallet.setValidateAction.awaitTransactionSuccessAsync( await validatorWallet.prepare.awaitTransactionSuccessAsync(
orderHashHex, orderHashHex,
ValidatorWalletDataType.Order,
validatorAction, validatorAction,
validSigner, signatureHashHex,
); );
} }
return signatureValidator.isValidOrderSignature.callAsync(order, order.makerAddress, signatureHex); return signatureValidator.isValidOrderSignature.callAsync(order, order.makerAddress, signatureHex);
@@ -589,47 +587,47 @@ describe('MixinSignatureValidator', () => {
signedOrder = await orderFactory.newSignedOrderAsync(); signedOrder = await orderFactory.newSignedOrderAsync();
}); });
it('should return true when SignatureType=OrderValidator, signature is valid and validator is approved', async () => { it('should return true when SignatureType=Validator, signature is valid and validator is approved', async () => {
const signature = Buffer.concat([ const signature = Buffer.concat([
ethUtil.toBuffer(signedOrder.signature).slice(0, SIGNATURE_LENGTH), ethUtil.toBuffer(signedOrder.signature).slice(0, SIGNATURE_LENGTH),
ethUtil.toBuffer(validatorWallet.address), ethUtil.toBuffer(validatorWallet.address),
ethUtil.toBuffer([SignatureType.OrderValidator]), ethUtil.toBuffer([SignatureType.Validator]),
]); ]);
const signatureHex = ethUtil.bufferToHex(signature); const signatureHex = ethUtil.bufferToHex(signature);
const isValidSignature = await validateCallAsync( const isValidSignature = await validateCallAsync(
signedOrder, signedOrder,
signerAddress, signerAddress,
signatureHex, signatureHex,
ValidatorWalletAction.ValidateSignature, ValidatorWalletAction.MatchSignatureHash,
); );
expect(isValidSignature).to.be.true(); expect(isValidSignature).to.be.true();
}); });
it('should return false when SignatureType=OrderValidator, signature is invalid and validator is approved', async () => { it('should return false when SignatureType=Validator, signature is invalid and validator is approved', async () => {
const signature = Buffer.concat([ const signature = Buffer.concat([
crypto.randomBytes(SIGNATURE_LENGTH), crypto.randomBytes(SIGNATURE_LENGTH),
ethUtil.toBuffer(validatorWallet.address), ethUtil.toBuffer(validatorWallet.address),
ethUtil.toBuffer([SignatureType.OrderValidator]), ethUtil.toBuffer([SignatureType.Validator]),
]); ]);
const signatureHex = ethUtil.bufferToHex(signature); const signatureHex = ethUtil.bufferToHex(signature);
const isValidSignature = await validateCallAsync( const isValidSignature = await validateCallAsync(
signedOrder, signedOrder,
signerAddress, signerAddress,
signatureHex, signatureHex,
ValidatorWalletAction.ValidateSignature, ValidatorWalletAction.MatchSignatureHash,
); );
expect(isValidSignature).to.be.false(); expect(isValidSignature).to.be.false();
}); });
it('should revert when `isValidOrderSignature` attempts to update state and SignatureType=OrderValidator', async () => { it('should revert when `isValidOrderSignature` attempts to update state and SignatureType=Validator', async () => {
const signature = Buffer.concat([ const signature = Buffer.concat([
ethUtil.toBuffer(signedOrder.signature).slice(0, SIGNATURE_LENGTH), ethUtil.toBuffer(signedOrder.signature).slice(0, SIGNATURE_LENGTH),
ethUtil.toBuffer(validatorWallet.address), ethUtil.toBuffer(validatorWallet.address),
ethUtil.toBuffer([SignatureType.OrderValidator]), ethUtil.toBuffer([SignatureType.Validator]),
]); ]);
const signatureHex = ethUtil.bufferToHex(signature); const signatureHex = ethUtil.bufferToHex(signature);
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
const expectedError = new ExchangeRevertErrors.SignatureOrderValidatorError( const expectedError = new ExchangeRevertErrors.SignatureValidatorError(
orderHashHex, orderHashHex,
signedOrder.makerAddress, signedOrder.makerAddress,
validatorWallet.address, validatorWallet.address,
@@ -640,15 +638,15 @@ describe('MixinSignatureValidator', () => {
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
it('should revert when `isValidOrderSignature` reverts and SignatureType=OrderValidator', async () => { it('should revert when `isValidOrderSignature` reverts and SignatureType=Validator', async () => {
const signature = Buffer.concat([ const signature = Buffer.concat([
ethUtil.toBuffer(signedOrder.signature).slice(0, SIGNATURE_LENGTH), ethUtil.toBuffer(signedOrder.signature).slice(0, SIGNATURE_LENGTH),
ethUtil.toBuffer(validatorWallet.address), ethUtil.toBuffer(validatorWallet.address),
ethUtil.toBuffer([SignatureType.OrderValidator]), ethUtil.toBuffer([SignatureType.Validator]),
]); ]);
const signatureHex = ethUtil.bufferToHex(signature); const signatureHex = ethUtil.bufferToHex(signature);
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
const expectedError = new ExchangeRevertErrors.SignatureOrderValidatorError( const expectedError = new ExchangeRevertErrors.SignatureValidatorError(
orderHashHex, orderHashHex,
signerAddress, signerAddress,
validatorWallet.address, validatorWallet.address,
@@ -659,9 +657,9 @@ describe('MixinSignatureValidator', () => {
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
it('should throw when SignatureType=OrderValidator, signature is valid and validator is not approved', async () => { it('should throw when SignatureType=Validator, signature is valid and validator is not approved', async () => {
// Set approval of signature validator to false // Set approval of signature validator to false
await signatureValidator.setOrderValidatorApproval.awaitTransactionSuccessAsync( await signatureValidator.setSignatureValidatorApproval.awaitTransactionSuccessAsync(
validatorWallet.address, validatorWallet.address,
false, false,
{ from: signerAddress }, { from: signerAddress },
@@ -669,39 +667,39 @@ describe('MixinSignatureValidator', () => {
const signature = Buffer.concat([ const signature = Buffer.concat([
ethUtil.toBuffer(signedOrder.signature).slice(0, SIGNATURE_LENGTH), ethUtil.toBuffer(signedOrder.signature).slice(0, SIGNATURE_LENGTH),
ethUtil.toBuffer(validatorWallet.address), ethUtil.toBuffer(validatorWallet.address),
ethUtil.toBuffer([SignatureType.OrderValidator]), ethUtil.toBuffer([SignatureType.Validator]),
]); ]);
const signatureHex = ethUtil.bufferToHex(signature); const signatureHex = ethUtil.bufferToHex(signature);
const tx = validateCallAsync( const tx = validateCallAsync(
signedOrder, signedOrder,
signerAddress, signerAddress,
signatureHex, signatureHex,
ValidatorWalletAction.ValidateSignature, ValidatorWalletAction.MatchSignatureHash,
); );
const expectedError = new ExchangeRevertErrors.SignatureOrderValidatorNotApprovedError( const expectedError = new ExchangeRevertErrors.SignatureValidatorNotApprovedError(
signerAddress, signerAddress,
validatorWallet.address, validatorWallet.address,
); );
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
it('should return true when SignatureType=OrderWallet and signature is valid', async () => { it('should return true when SignatureType=EIP1271Wallet and signature is valid', async () => {
signedOrder.makerAddress = validatorWallet.address; signedOrder.makerAddress = validatorWallet.address;
const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.OrderWallet])]); const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.EIP1271Wallet])]);
const signatureHex = ethUtil.bufferToHex(signature); const signatureHex = ethUtil.bufferToHex(signature);
// Validate signature // Validate signature
const isValidSignature = await validateCallAsync( const isValidSignature = await validateCallAsync(
signedOrder, signedOrder,
validatorWallet.address, validatorWallet.address,
signatureHex, signatureHex,
ValidatorWalletAction.ValidateSignature, ValidatorWalletAction.MatchSignatureHash,
); );
expect(isValidSignature).to.be.true(); expect(isValidSignature).to.be.true();
}); });
it('should return false when SignatureType=OrderWallet and signature is invalid', async () => { it('should return false when SignatureType=EIP1271Wallet and signature is invalid', async () => {
signedOrder.makerAddress = validatorWallet.address; signedOrder.makerAddress = validatorWallet.address;
const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.OrderWallet])]); const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.EIP1271Wallet])]);
const signatureHex = ethUtil.bufferToHex(signature); const signatureHex = ethUtil.bufferToHex(signature);
// Validate signature // Validate signature
const isValidSignature = await validateCallAsync( const isValidSignature = await validateCallAsync(
@@ -713,12 +711,12 @@ describe('MixinSignatureValidator', () => {
expect(isValidSignature).to.be.false(); expect(isValidSignature).to.be.false();
}); });
it('should revert when validator attempts to update state and SignatureType=OrderWallet', async () => { it('should revert when validator attempts to update state and SignatureType=EIP1271Wallet', async () => {
signedOrder.makerAddress = validatorWallet.address; signedOrder.makerAddress = validatorWallet.address;
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.OrderWallet])]); const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.EIP1271Wallet])]);
const signatureHex = ethUtil.bufferToHex(signature); const signatureHex = ethUtil.bufferToHex(signature);
const expectedError = new ExchangeRevertErrors.SignatureOrderWalletError( const expectedError = new ExchangeRevertErrors.SignatureWalletError(
orderHashHex, orderHashHex,
validatorWallet.address, validatorWallet.address,
signatureHex, signatureHex,
@@ -733,12 +731,12 @@ describe('MixinSignatureValidator', () => {
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
it('should revert when validator reverts and SignatureType=OrderWallet', async () => { it('should revert when validator reverts and SignatureType=EIP1271Wallet', async () => {
signedOrder.makerAddress = validatorWallet.address; signedOrder.makerAddress = validatorWallet.address;
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.OrderWallet])]); const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.EIP1271Wallet])]);
const signatureHex = ethUtil.bufferToHex(signature); const signatureHex = ethUtil.bufferToHex(signature);
const expectedError = new ExchangeRevertErrors.SignatureOrderWalletError( const expectedError = new ExchangeRevertErrors.SignatureWalletError(
orderHashHex, orderHashHex,
validatorWallet.address, validatorWallet.address,
signatureHex, signatureHex,
@@ -753,23 +751,23 @@ describe('MixinSignatureValidator', () => {
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
it('should return true when SignatureType=EIP1271OrderWallet and signature is valid', async () => { it('should return true when SignatureType=EIP1271Wallet and signature is valid', async () => {
signedOrder.makerAddress = validatorWallet.address; signedOrder.makerAddress = validatorWallet.address;
const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.EIP1271OrderWallet])]); const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.EIP1271Wallet])]);
const signatureHex = ethUtil.bufferToHex(signature); const signatureHex = ethUtil.bufferToHex(signature);
// Validate signature // Validate signature
const isValidSignature = await validateCallAsync( const isValidSignature = await validateCallAsync(
signedOrder, signedOrder,
validatorWallet.address, validatorWallet.address,
signatureHex, signatureHex,
ValidatorWalletAction.ValidateSignature, ValidatorWalletAction.MatchSignatureHash,
); );
expect(isValidSignature).to.be.true(); expect(isValidSignature).to.be.true();
}); });
it('should return false when SignatureType=EIP1271OrderWallet and signature is invalid', async () => { it('should return false when SignatureType=EIP1271Wallet and signature is invalid', async () => {
signedOrder.makerAddress = validatorWallet.address; signedOrder.makerAddress = validatorWallet.address;
const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.EIP1271OrderWallet])]); const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.EIP1271Wallet])]);
const signatureHex = ethUtil.bufferToHex(signature); const signatureHex = ethUtil.bufferToHex(signature);
// Validate signature // Validate signature
const isValidSignature = await validateCallAsync( const isValidSignature = await validateCallAsync(
@@ -781,12 +779,12 @@ describe('MixinSignatureValidator', () => {
expect(isValidSignature).to.be.false(); expect(isValidSignature).to.be.false();
}); });
it('should revert when validator attempts to update state and SignatureType=EIP1271OrderWallet', async () => { it('should revert when validator attempts to update state and SignatureType=EIP1271Wallet', async () => {
signedOrder.makerAddress = validatorWallet.address; signedOrder.makerAddress = validatorWallet.address;
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.EIP1271OrderWallet])]); const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.EIP1271Wallet])]);
const signatureHex = ethUtil.bufferToHex(signature); const signatureHex = ethUtil.bufferToHex(signature);
const expectedError = new ExchangeRevertErrors.SignatureOrderWalletError( const expectedError = new ExchangeRevertErrors.SignatureWalletError(
orderHashHex, orderHashHex,
validatorWallet.address, validatorWallet.address,
signatureHex, signatureHex,
@@ -801,12 +799,12 @@ describe('MixinSignatureValidator', () => {
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
it('should revert when validator reverts and SignatureType=EIP1271OrderWallet', async () => { it('should revert when validator reverts and SignatureType=EIP1271Wallet', async () => {
signedOrder.makerAddress = validatorWallet.address; signedOrder.makerAddress = validatorWallet.address;
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.EIP1271OrderWallet])]); const signature = Buffer.concat([ethUtil.toBuffer([SignatureType.EIP1271Wallet])]);
const signatureHex = ethUtil.bufferToHex(signature); const signatureHex = ethUtil.bufferToHex(signature);
const expectedError = new ExchangeRevertErrors.SignatureOrderWalletError( const expectedError = new ExchangeRevertErrors.SignatureWalletError(
orderHashHex, orderHashHex,
validatorWallet.address, validatorWallet.address,
signatureHex, signatureHex,
@@ -861,42 +859,6 @@ describe('MixinSignatureValidator', () => {
expect(logArgs.validatorAddress).to.equal(validatorWallet.address); expect(logArgs.validatorAddress).to.equal(validatorWallet.address);
expect(logArgs.approved).to.equal(approval); expect(logArgs.approved).to.equal(approval);
}); });
it('should emit a SignatureValidatorApprovalSet with correct args when an order validator is approved', async () => {
const approval = true;
const res = await signatureValidator.setOrderValidatorApproval.awaitTransactionSuccessAsync(
validatorWallet.address,
approval,
{
from: signerAddress,
},
);
expect(res.logs.length).to.equal(1);
const log = signatureValidatorLogDecoder.decodeLogOrThrow(res.logs[0]) as LogWithDecodedArgs<
TestSignatureValidatorSignatureValidatorApprovalEventArgs
>;
const logArgs = log.args;
expect(logArgs.signerAddress).to.equal(signerAddress);
expect(logArgs.validatorAddress).to.equal(validatorWallet.address);
expect(logArgs.approved).to.equal(approval);
});
it('should emit a SignatureValidatorApprovalSet with correct args when am order validator is disapproved', async () => {
const approval = false;
const res = await signatureValidator.setOrderValidatorApproval.awaitTransactionSuccessAsync(
validatorWallet.address,
approval,
{
from: signerAddress,
},
);
expect(res.logs.length).to.equal(1);
const log = signatureValidatorLogDecoder.decodeLogOrThrow(res.logs[0]) as LogWithDecodedArgs<
TestSignatureValidatorSignatureValidatorApprovalEventArgs
>;
const logArgs = log.args;
expect(logArgs.signerAddress).to.equal(signerAddress);
expect(logArgs.validatorAddress).to.equal(validatorWallet.address);
expect(logArgs.approved).to.equal(approval);
});
}); });
}); });
// tslint:disable:max-file-line-count // tslint:disable:max-file-line-count

View File

@@ -620,51 +620,6 @@ describe('Exchange transactions', () => {
expect(validatorApprovalLogArgs.approved).to.eq(shouldApprove); expect(validatorApprovalLogArgs.approved).to.eq(shouldApprove);
}); });
}); });
describe('setOrderValidatorApproval', () => {
it('should approve a validator for the signer', async () => {
const shouldApprove = true;
const data = exchangeInstance.setOrderValidatorApproval.getABIEncodedTransactionData(
validatorAddress,
shouldApprove,
);
const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
const transactionReceipt = await exchangeWrapper.executeTransactionAsync(transaction, senderAddress);
const validatorApprovalLogs = transactionReceipt.logs.filter(
log =>
(log as LogWithDecodedArgs<ExchangeSignatureValidatorApprovalEventArgs>).event ===
'SignatureValidatorApproval',
);
expect(validatorApprovalLogs.length).to.eq(1);
const validatorApprovalLogArgs = (validatorApprovalLogs[0] as LogWithDecodedArgs<
ExchangeSignatureValidatorApprovalEventArgs
>).args;
expect(validatorApprovalLogArgs.signerAddress).to.eq(takerAddress);
expect(validatorApprovalLogArgs.validatorAddress).to.eq(validatorAddress);
expect(validatorApprovalLogArgs.approved).to.eq(shouldApprove);
});
it('should approve a validator for the caller if called without a signature', async () => {
const shouldApprove = true;
const data = exchangeInstance.setOrderValidatorApproval.getABIEncodedTransactionData(
validatorAddress,
shouldApprove,
);
const transaction = await takerTransactionFactory.newSignedTransactionAsync({ data });
transaction.signature = constants.NULL_BYTES;
const transactionReceipt = await exchangeWrapper.executeTransactionAsync(transaction, takerAddress);
const validatorApprovalLogs = transactionReceipt.logs.filter(
log =>
(log as LogWithDecodedArgs<ExchangeSignatureValidatorApprovalEventArgs>).event ===
'SignatureValidatorApproval',
);
expect(validatorApprovalLogs.length).to.eq(1);
const validatorApprovalLogArgs = (validatorApprovalLogs[0] as LogWithDecodedArgs<
ExchangeSignatureValidatorApprovalEventArgs
>).args;
expect(validatorApprovalLogArgs.signerAddress).to.eq(takerAddress);
expect(validatorApprovalLogArgs.validatorAddress).to.eq(validatorAddress);
expect(validatorApprovalLogArgs.approved).to.eq(shouldApprove);
});
});
describe('batchExecuteTransactions', () => { describe('batchExecuteTransactions', () => {
it('should successfully call fillOrder via 2 transactions with different taker signatures', async () => { it('should successfully call fillOrder via 2 transactions with different taker signatures', async () => {
const order1 = await orderFactory.newSignedOrderAsync(); const order1 = await orderFactory.newSignedOrderAsync();

View File

@@ -14,7 +14,6 @@ export const constants = {
'CANCEL_ORDERS_UP_TO', 'CANCEL_ORDERS_UP_TO',
'PRE_SIGN', 'PRE_SIGN',
'SET_SIGNATURE_VALIDATOR_APPROVAL', 'SET_SIGNATURE_VALIDATOR_APPROVAL',
'SET_ORDER_VALIDATOR_APPROVAL',
], ],
SINGLE_FILL_FN_NAMES: [ SINGLE_FILL_FN_NAMES: [
ExchangeFunctionName.FillOrder, ExchangeFunctionName.FillOrder,
@@ -39,6 +38,13 @@ export enum ValidatorWalletAction {
Accept = 1, Accept = 1,
Revert = 2, Revert = 2,
UpdateState = 3, UpdateState = 3,
ValidateSignature = 4, MatchSignatureHash = 4,
NTypes = 5, NTypes = 5,
} }
export enum ValidatorWalletDataType {
None = 0,
Order = 1,
ZeroExTransaction = 2,
NTypes = 3,
}

View File

@@ -46,11 +46,6 @@ export const exchangeDataEncoder = {
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
true, true,
); );
} else if (fnName === ExchangeFunctionName.SetOrderValidatorApproval) {
data = exchangeInstance.setOrderValidatorApproval.getABIEncodedTransactionData(
constants.NULL_ADDRESS,
true,
);
} else { } else {
throw new Error(`Error: ${fnName} not a supported function`); throw new Error(`Error: ${fnName} not a supported function`);
} }

View File

@@ -24,5 +24,4 @@ export enum ExchangeFunctionName {
CancelOrdersUpTo = 'cancelOrdersUpTo', CancelOrdersUpTo = 'cancelOrdersUpTo',
PreSign = 'preSign', PreSign = 'preSign',
SetSignatureValidatorApproval = 'setSignatureValidatorApproval', SetSignatureValidatorApproval = 'setSignatureValidatorApproval',
SetOrderValidatorApproval = 'setOrderValidatorApproval',
} }