508 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			508 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import { BlockchainLifecycle } from '@0xproject/dev-utils';
 | 
						|
import { addSignedMessagePrefix, assetDataUtils, orderHashUtils } from '@0xproject/order-utils';
 | 
						|
import { RevertReason, SignatureType, SignedOrder, SignerType } from '@0xproject/types';
 | 
						|
import * as chai from 'chai';
 | 
						|
import { LogWithDecodedArgs } from 'ethereum-types';
 | 
						|
import ethUtil = require('ethereumjs-util');
 | 
						|
 | 
						|
import {
 | 
						|
    TestSignatureValidatorContract,
 | 
						|
    TestSignatureValidatorSignatureValidatorApprovalEventArgs,
 | 
						|
} from '../../generated_contract_wrappers/test_signature_validator';
 | 
						|
import { ValidatorContract } from '../../generated_contract_wrappers/validator';
 | 
						|
import { WalletContract } from '../../generated_contract_wrappers/wallet';
 | 
						|
import { addressUtils } from '../utils/address_utils';
 | 
						|
import { artifacts } from '../utils/artifacts';
 | 
						|
import { expectContractCallFailed } from '../utils/assertions';
 | 
						|
import { chaiSetup } from '../utils/chai_setup';
 | 
						|
import { constants } from '../utils/constants';
 | 
						|
import { LogDecoder } from '../utils/log_decoder';
 | 
						|
import { OrderFactory } from '../utils/order_factory';
 | 
						|
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
 | 
						|
 | 
						|
chaiSetup.configure();
 | 
						|
const expect = chai.expect;
 | 
						|
 | 
						|
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
 | 
						|
// tslint:disable:no-unnecessary-type-assertion
 | 
						|
describe('MixinSignatureValidator', () => {
 | 
						|
    let signedOrder: SignedOrder;
 | 
						|
    let orderFactory: OrderFactory;
 | 
						|
    let signatureValidator: TestSignatureValidatorContract;
 | 
						|
    let testWallet: WalletContract;
 | 
						|
    let testValidator: ValidatorContract;
 | 
						|
    let signerAddress: string;
 | 
						|
    let signerPrivateKey: Buffer;
 | 
						|
    let notSignerAddress: string;
 | 
						|
    let notSignerPrivateKey: Buffer;
 | 
						|
    let signatureValidatorLogDecoder: LogDecoder;
 | 
						|
 | 
						|
    before(async () => {
 | 
						|
        await blockchainLifecycle.startAsync();
 | 
						|
    });
 | 
						|
    after(async () => {
 | 
						|
        await blockchainLifecycle.revertAsync();
 | 
						|
    });
 | 
						|
    before(async () => {
 | 
						|
        const accounts = await web3Wrapper.getAvailableAddressesAsync();
 | 
						|
        const makerAddress = accounts[0];
 | 
						|
        signerAddress = makerAddress;
 | 
						|
        notSignerAddress = accounts[1];
 | 
						|
        signatureValidator = await TestSignatureValidatorContract.deployFrom0xArtifactAsync(
 | 
						|
            artifacts.TestSignatureValidator,
 | 
						|
            provider,
 | 
						|
            txDefaults,
 | 
						|
        );
 | 
						|
        testWallet = await WalletContract.deployFrom0xArtifactAsync(
 | 
						|
            artifacts.Wallet,
 | 
						|
            provider,
 | 
						|
            txDefaults,
 | 
						|
            signerAddress,
 | 
						|
        );
 | 
						|
        testValidator = await ValidatorContract.deployFrom0xArtifactAsync(
 | 
						|
            artifacts.Validator,
 | 
						|
            provider,
 | 
						|
            txDefaults,
 | 
						|
            signerAddress,
 | 
						|
        );
 | 
						|
        signatureValidatorLogDecoder = new LogDecoder(web3Wrapper, signatureValidator.address);
 | 
						|
        await web3Wrapper.awaitTransactionSuccessAsync(
 | 
						|
            await signatureValidator.setSignatureValidatorApproval.sendTransactionAsync(testValidator.address, true, {
 | 
						|
                from: signerAddress,
 | 
						|
            }),
 | 
						|
            constants.AWAIT_TRANSACTION_MINED_MS,
 | 
						|
        );
 | 
						|
 | 
						|
        const defaultOrderParams = {
 | 
						|
            ...constants.STATIC_ORDER_PARAMS,
 | 
						|
            exchangeAddress: signatureValidator.address,
 | 
						|
            makerAddress,
 | 
						|
            feeRecipientAddress: addressUtils.generatePseudoRandomAddress(),
 | 
						|
            makerAssetData: assetDataUtils.encodeERC20AssetData(addressUtils.generatePseudoRandomAddress()),
 | 
						|
            takerAssetData: assetDataUtils.encodeERC20AssetData(addressUtils.generatePseudoRandomAddress()),
 | 
						|
        };
 | 
						|
        signerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)];
 | 
						|
        notSignerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(notSignerAddress)];
 | 
						|
        orderFactory = new OrderFactory(signerPrivateKey, defaultOrderParams);
 | 
						|
    });
 | 
						|
 | 
						|
    beforeEach(async () => {
 | 
						|
        await blockchainLifecycle.startAsync();
 | 
						|
    });
 | 
						|
    afterEach(async () => {
 | 
						|
        await blockchainLifecycle.revertAsync();
 | 
						|
    });
 | 
						|
 | 
						|
    describe('isValidSignature', () => {
 | 
						|
        beforeEach(async () => {
 | 
						|
            signedOrder = await orderFactory.newSignedOrderAsync();
 | 
						|
        });
 | 
						|
 | 
						|
        it('should revert when signature is empty', async () => {
 | 
						|
            const emptySignature = '0x';
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            return expectContractCallFailed(
 | 
						|
                signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                    orderHashHex,
 | 
						|
                    signedOrder.makerAddress,
 | 
						|
                    emptySignature,
 | 
						|
                ),
 | 
						|
                RevertReason.LengthGreaterThan0Required,
 | 
						|
            );
 | 
						|
        });
 | 
						|
 | 
						|
        it('should revert when signature type is unsupported', async () => {
 | 
						|
            const unsupportedSignatureType = SignatureType.NSignatureTypes;
 | 
						|
            const unsupportedSignatureHex = '0x' + Buffer.from([unsupportedSignatureType]).toString('hex');
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            return expectContractCallFailed(
 | 
						|
                signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                    orderHashHex,
 | 
						|
                    signedOrder.makerAddress,
 | 
						|
                    unsupportedSignatureHex,
 | 
						|
                ),
 | 
						|
                RevertReason.SignatureUnsupported,
 | 
						|
            );
 | 
						|
        });
 | 
						|
 | 
						|
        it('should revert when SignatureType=Illegal', async () => {
 | 
						|
            const unsupportedSignatureHex = '0x' + Buffer.from([SignatureType.Illegal]).toString('hex');
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            return expectContractCallFailed(
 | 
						|
                signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                    orderHashHex,
 | 
						|
                    signedOrder.makerAddress,
 | 
						|
                    unsupportedSignatureHex,
 | 
						|
                ),
 | 
						|
                RevertReason.SignatureIllegal,
 | 
						|
            );
 | 
						|
        });
 | 
						|
 | 
						|
        it('should return false when SignatureType=Invalid and signature has a length of zero', async () => {
 | 
						|
            const signatureHex = '0x' + Buffer.from([SignatureType.Invalid]).toString('hex');
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                orderHashHex,
 | 
						|
                signedOrder.makerAddress,
 | 
						|
                signatureHex,
 | 
						|
            );
 | 
						|
            expect(isValidSignature).to.be.false();
 | 
						|
        });
 | 
						|
 | 
						|
        it('should revert when SignatureType=Invalid and signature length is non-zero', async () => {
 | 
						|
            const fillerData = ethUtil.toBuffer('0xdeadbeef');
 | 
						|
            const signatureType = ethUtil.toBuffer(`0x${SignatureType.Invalid}`);
 | 
						|
            const signatureBuffer = Buffer.concat([fillerData, signatureType]);
 | 
						|
            const signatureHex = ethUtil.bufferToHex(signatureBuffer);
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            return expectContractCallFailed(
 | 
						|
                signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                    orderHashHex,
 | 
						|
                    signedOrder.makerAddress,
 | 
						|
                    signatureHex,
 | 
						|
                ),
 | 
						|
                RevertReason.Length0Required,
 | 
						|
            );
 | 
						|
        });
 | 
						|
 | 
						|
        it('should return true when SignatureType=EIP712 and signature is valid', async () => {
 | 
						|
            // Create EIP712 signature
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            const orderHashBuffer = ethUtil.toBuffer(orderHashHex);
 | 
						|
            const ecSignature = ethUtil.ecsign(orderHashBuffer, signerPrivateKey);
 | 
						|
            // Create 0x signature from EIP712 signature
 | 
						|
            const signature = Buffer.concat([
 | 
						|
                ethUtil.toBuffer(ecSignature.v),
 | 
						|
                ecSignature.r,
 | 
						|
                ecSignature.s,
 | 
						|
                ethUtil.toBuffer(`0x${SignatureType.EIP712}`),
 | 
						|
            ]);
 | 
						|
            const signatureHex = ethUtil.bufferToHex(signature);
 | 
						|
            // Validate signature
 | 
						|
            const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                orderHashHex,
 | 
						|
                signerAddress,
 | 
						|
                signatureHex,
 | 
						|
            );
 | 
						|
            expect(isValidSignature).to.be.true();
 | 
						|
        });
 | 
						|
 | 
						|
        it('should return false when SignatureType=EIP712 and signature is invalid', async () => {
 | 
						|
            // Create EIP712 signature
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            const orderHashBuffer = ethUtil.toBuffer(orderHashHex);
 | 
						|
            const ecSignature = ethUtil.ecsign(orderHashBuffer, signerPrivateKey);
 | 
						|
            // Create 0x signature from EIP712 signature
 | 
						|
            const signature = Buffer.concat([
 | 
						|
                ethUtil.toBuffer(ecSignature.v),
 | 
						|
                ecSignature.r,
 | 
						|
                ecSignature.s,
 | 
						|
                ethUtil.toBuffer(`0x${SignatureType.EIP712}`),
 | 
						|
            ]);
 | 
						|
            const signatureHex = ethUtil.bufferToHex(signature);
 | 
						|
            // Validate signature.
 | 
						|
            // This will fail because `signerAddress` signed the message, but we're passing in `notSignerAddress`
 | 
						|
            const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                orderHashHex,
 | 
						|
                notSignerAddress,
 | 
						|
                signatureHex,
 | 
						|
            );
 | 
						|
            expect(isValidSignature).to.be.false();
 | 
						|
        });
 | 
						|
 | 
						|
        it('should return true when SignatureType=EthSign and signature is valid', async () => {
 | 
						|
            // Create EthSign signature
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            const orderHashWithEthSignPrefixHex = addSignedMessagePrefix(orderHashHex, SignerType.Default);
 | 
						|
            const orderHashWithEthSignPrefixBuffer = ethUtil.toBuffer(orderHashWithEthSignPrefixHex);
 | 
						|
            const ecSignature = ethUtil.ecsign(orderHashWithEthSignPrefixBuffer, signerPrivateKey);
 | 
						|
            // Create 0x signature from EthSign signature
 | 
						|
            const signature = Buffer.concat([
 | 
						|
                ethUtil.toBuffer(ecSignature.v),
 | 
						|
                ecSignature.r,
 | 
						|
                ecSignature.s,
 | 
						|
                ethUtil.toBuffer(`0x${SignatureType.EthSign}`),
 | 
						|
            ]);
 | 
						|
            const signatureHex = ethUtil.bufferToHex(signature);
 | 
						|
            // Validate signature
 | 
						|
            const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                orderHashHex,
 | 
						|
                signerAddress,
 | 
						|
                signatureHex,
 | 
						|
            );
 | 
						|
            expect(isValidSignature).to.be.true();
 | 
						|
        });
 | 
						|
 | 
						|
        it('should return false when SignatureType=EthSign and signature is invalid', async () => {
 | 
						|
            // Create EthSign signature
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            const orderHashWithEthSignPrefixHex = addSignedMessagePrefix(orderHashHex, SignerType.Default);
 | 
						|
            const orderHashWithEthSignPrefixBuffer = ethUtil.toBuffer(orderHashWithEthSignPrefixHex);
 | 
						|
            const ecSignature = ethUtil.ecsign(orderHashWithEthSignPrefixBuffer, signerPrivateKey);
 | 
						|
            // Create 0x signature from EthSign signature
 | 
						|
            const signature = Buffer.concat([
 | 
						|
                ethUtil.toBuffer(ecSignature.v),
 | 
						|
                ecSignature.r,
 | 
						|
                ecSignature.s,
 | 
						|
                ethUtil.toBuffer(`0x${SignatureType.EthSign}`),
 | 
						|
            ]);
 | 
						|
            const signatureHex = ethUtil.bufferToHex(signature);
 | 
						|
            // Validate signature.
 | 
						|
            // This will fail because `signerAddress` signed the message, but we're passing in `notSignerAddress`
 | 
						|
            const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                orderHashHex,
 | 
						|
                notSignerAddress,
 | 
						|
                signatureHex,
 | 
						|
            );
 | 
						|
            expect(isValidSignature).to.be.false();
 | 
						|
        });
 | 
						|
 | 
						|
        it('should return true when SignatureType=Caller and signer is caller', async () => {
 | 
						|
            const signature = ethUtil.toBuffer(`0x${SignatureType.Caller}`);
 | 
						|
            const signatureHex = ethUtil.bufferToHex(signature);
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                orderHashHex,
 | 
						|
                signerAddress,
 | 
						|
                signatureHex,
 | 
						|
                { from: signerAddress },
 | 
						|
            );
 | 
						|
            expect(isValidSignature).to.be.true();
 | 
						|
        });
 | 
						|
 | 
						|
        it('should return false when SignatureType=Caller and signer is not caller', async () => {
 | 
						|
            const signature = ethUtil.toBuffer(`0x${SignatureType.Caller}`);
 | 
						|
            const signatureHex = ethUtil.bufferToHex(signature);
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                orderHashHex,
 | 
						|
                signerAddress,
 | 
						|
                signatureHex,
 | 
						|
                { from: notSignerAddress },
 | 
						|
            );
 | 
						|
            expect(isValidSignature).to.be.false();
 | 
						|
        });
 | 
						|
 | 
						|
        it('should return true when SignatureType=Wallet and signature is valid', async () => {
 | 
						|
            // Create EIP712 signature
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            const orderHashBuffer = ethUtil.toBuffer(orderHashHex);
 | 
						|
            const ecSignature = ethUtil.ecsign(orderHashBuffer, signerPrivateKey);
 | 
						|
            // Create 0x signature from EIP712 signature
 | 
						|
            const signature = Buffer.concat([
 | 
						|
                ethUtil.toBuffer(ecSignature.v),
 | 
						|
                ecSignature.r,
 | 
						|
                ecSignature.s,
 | 
						|
                ethUtil.toBuffer(`0x${SignatureType.Wallet}`),
 | 
						|
            ]);
 | 
						|
            const signatureHex = ethUtil.bufferToHex(signature);
 | 
						|
            // Validate signature
 | 
						|
            const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                orderHashHex,
 | 
						|
                testWallet.address,
 | 
						|
                signatureHex,
 | 
						|
            );
 | 
						|
            expect(isValidSignature).to.be.true();
 | 
						|
        });
 | 
						|
 | 
						|
        it('should return false when SignatureType=Wallet and signature is invalid', async () => {
 | 
						|
            // Create EIP712 signature using a private key that does not belong to the wallet owner.
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            const orderHashBuffer = ethUtil.toBuffer(orderHashHex);
 | 
						|
            const notWalletOwnerPrivateKey = notSignerPrivateKey;
 | 
						|
            const ecSignature = ethUtil.ecsign(orderHashBuffer, notWalletOwnerPrivateKey);
 | 
						|
            // Create 0x signature from EIP712 signature
 | 
						|
            const signature = Buffer.concat([
 | 
						|
                ethUtil.toBuffer(ecSignature.v),
 | 
						|
                ecSignature.r,
 | 
						|
                ecSignature.s,
 | 
						|
                ethUtil.toBuffer(`0x${SignatureType.Wallet}`),
 | 
						|
            ]);
 | 
						|
            const signatureHex = ethUtil.bufferToHex(signature);
 | 
						|
            // Validate signature
 | 
						|
            const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                orderHashHex,
 | 
						|
                testWallet.address,
 | 
						|
                signatureHex,
 | 
						|
            );
 | 
						|
            expect(isValidSignature).to.be.false();
 | 
						|
        });
 | 
						|
 | 
						|
        it('should return true when SignatureType=Validator, signature is valid and validator is approved', async () => {
 | 
						|
            const validatorAddress = ethUtil.toBuffer(`${testValidator.address}`);
 | 
						|
            const signatureType = ethUtil.toBuffer(`0x${SignatureType.Validator}`);
 | 
						|
            const signature = Buffer.concat([validatorAddress, signatureType]);
 | 
						|
            const signatureHex = ethUtil.bufferToHex(signature);
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                orderHashHex,
 | 
						|
                signerAddress,
 | 
						|
                signatureHex,
 | 
						|
            );
 | 
						|
            expect(isValidSignature).to.be.true();
 | 
						|
        });
 | 
						|
 | 
						|
        it('should return false when SignatureType=Validator, signature is invalid and validator is approved', async () => {
 | 
						|
            const validatorAddress = ethUtil.toBuffer(`${testValidator.address}`);
 | 
						|
            const signatureType = ethUtil.toBuffer(`0x${SignatureType.Validator}`);
 | 
						|
            const signature = Buffer.concat([validatorAddress, signatureType]);
 | 
						|
            const signatureHex = ethUtil.bufferToHex(signature);
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            // This will return false because we signed the message with `signerAddress`, but
 | 
						|
            // are validating against `notSignerAddress`
 | 
						|
            const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                orderHashHex,
 | 
						|
                notSignerAddress,
 | 
						|
                signatureHex,
 | 
						|
            );
 | 
						|
            expect(isValidSignature).to.be.false();
 | 
						|
        });
 | 
						|
 | 
						|
        it('should return false when SignatureType=Validator, signature is valid and validator is not approved', async () => {
 | 
						|
            // Set approval of signature validator to false
 | 
						|
            await web3Wrapper.awaitTransactionSuccessAsync(
 | 
						|
                await signatureValidator.setSignatureValidatorApproval.sendTransactionAsync(
 | 
						|
                    testValidator.address,
 | 
						|
                    false,
 | 
						|
                    { from: signerAddress },
 | 
						|
                ),
 | 
						|
                constants.AWAIT_TRANSACTION_MINED_MS,
 | 
						|
            );
 | 
						|
            // Validate signature
 | 
						|
            const validatorAddress = ethUtil.toBuffer(`${testValidator.address}`);
 | 
						|
            const signatureType = ethUtil.toBuffer(`0x${SignatureType.Validator}`);
 | 
						|
            const signature = Buffer.concat([validatorAddress, signatureType]);
 | 
						|
            const signatureHex = ethUtil.bufferToHex(signature);
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                orderHashHex,
 | 
						|
                signerAddress,
 | 
						|
                signatureHex,
 | 
						|
            );
 | 
						|
            expect(isValidSignature).to.be.false();
 | 
						|
        });
 | 
						|
 | 
						|
        it('should return true when SignatureType=Trezor and signature is valid', async () => {
 | 
						|
            // Create Trezor signature
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            const orderHashWithTrezorPrefixHex = addSignedMessagePrefix(orderHashHex, SignerType.Trezor);
 | 
						|
            const orderHashWithTrezorPrefixBuffer = ethUtil.toBuffer(orderHashWithTrezorPrefixHex);
 | 
						|
            const ecSignature = ethUtil.ecsign(orderHashWithTrezorPrefixBuffer, signerPrivateKey);
 | 
						|
            // Create 0x signature from Trezor signature
 | 
						|
            const signature = Buffer.concat([
 | 
						|
                ethUtil.toBuffer(ecSignature.v),
 | 
						|
                ecSignature.r,
 | 
						|
                ecSignature.s,
 | 
						|
                ethUtil.toBuffer(`0x${SignatureType.Trezor}`),
 | 
						|
            ]);
 | 
						|
            const signatureHex = ethUtil.bufferToHex(signature);
 | 
						|
            // Validate signature
 | 
						|
            const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                orderHashHex,
 | 
						|
                signerAddress,
 | 
						|
                signatureHex,
 | 
						|
            );
 | 
						|
            expect(isValidSignature).to.be.true();
 | 
						|
        });
 | 
						|
 | 
						|
        it('should return false when SignatureType=Trezor and signature is invalid', async () => {
 | 
						|
            // Create Trezor signature
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            const orderHashWithTrezorPrefixHex = addSignedMessagePrefix(orderHashHex, SignerType.Trezor);
 | 
						|
            const orderHashWithTrezorPrefixBuffer = ethUtil.toBuffer(orderHashWithTrezorPrefixHex);
 | 
						|
            const ecSignature = ethUtil.ecsign(orderHashWithTrezorPrefixBuffer, signerPrivateKey);
 | 
						|
            // Create 0x signature from Trezor signature
 | 
						|
            const signature = Buffer.concat([
 | 
						|
                ethUtil.toBuffer(ecSignature.v),
 | 
						|
                ecSignature.r,
 | 
						|
                ecSignature.s,
 | 
						|
                ethUtil.toBuffer(`0x${SignatureType.Trezor}`),
 | 
						|
            ]);
 | 
						|
            const signatureHex = ethUtil.bufferToHex(signature);
 | 
						|
            // Validate signature.
 | 
						|
            // This will fail because `signerAddress` signed the message, but we're passing in `notSignerAddress`
 | 
						|
            const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                orderHashHex,
 | 
						|
                notSignerAddress,
 | 
						|
                signatureHex,
 | 
						|
            );
 | 
						|
            expect(isValidSignature).to.be.false();
 | 
						|
        });
 | 
						|
 | 
						|
        it('should return true when SignatureType=Presigned and signer has presigned hash', async () => {
 | 
						|
            // Presign hash
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            await web3Wrapper.awaitTransactionSuccessAsync(
 | 
						|
                await signatureValidator.preSign.sendTransactionAsync(
 | 
						|
                    orderHashHex,
 | 
						|
                    signedOrder.makerAddress,
 | 
						|
                    signedOrder.signature,
 | 
						|
                ),
 | 
						|
                constants.AWAIT_TRANSACTION_MINED_MS,
 | 
						|
            );
 | 
						|
            // Validate presigned signature
 | 
						|
            const signature = ethUtil.toBuffer(`0x${SignatureType.PreSigned}`);
 | 
						|
            const signatureHex = ethUtil.bufferToHex(signature);
 | 
						|
            const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                orderHashHex,
 | 
						|
                signedOrder.makerAddress,
 | 
						|
                signatureHex,
 | 
						|
            );
 | 
						|
            expect(isValidSignature).to.be.true();
 | 
						|
        });
 | 
						|
 | 
						|
        it('should return false when SignatureType=Presigned and signer has not presigned hash', async () => {
 | 
						|
            const signature = ethUtil.toBuffer(`0x${SignatureType.PreSigned}`);
 | 
						|
            const signatureHex = ethUtil.bufferToHex(signature);
 | 
						|
            const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
 | 
						|
            const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
 | 
						|
                orderHashHex,
 | 
						|
                signedOrder.makerAddress,
 | 
						|
                signatureHex,
 | 
						|
            );
 | 
						|
            expect(isValidSignature).to.be.false();
 | 
						|
        });
 | 
						|
    });
 | 
						|
 | 
						|
    describe('setSignatureValidatorApproval', () => {
 | 
						|
        it('should emit a SignatureValidatorApprovalSet with correct args when a validator is approved', async () => {
 | 
						|
            const approval = true;
 | 
						|
            const res = await signatureValidatorLogDecoder.getTxWithDecodedLogsAsync(
 | 
						|
                await signatureValidator.setSignatureValidatorApproval.sendTransactionAsync(
 | 
						|
                    testValidator.address,
 | 
						|
                    approval,
 | 
						|
                    {
 | 
						|
                        from: signerAddress,
 | 
						|
                    },
 | 
						|
                ),
 | 
						|
            );
 | 
						|
            expect(res.logs.length).to.equal(1);
 | 
						|
            const log = res.logs[0] as LogWithDecodedArgs<TestSignatureValidatorSignatureValidatorApprovalEventArgs>;
 | 
						|
            const logArgs = log.args;
 | 
						|
            expect(logArgs.signerAddress).to.equal(signerAddress);
 | 
						|
            expect(logArgs.validatorAddress).to.equal(testValidator.address);
 | 
						|
            expect(logArgs.approved).to.equal(approval);
 | 
						|
        });
 | 
						|
        it('should emit a SignatureValidatorApprovalSet with correct args when a validator is disapproved', async () => {
 | 
						|
            const approval = false;
 | 
						|
            const res = await signatureValidatorLogDecoder.getTxWithDecodedLogsAsync(
 | 
						|
                await signatureValidator.setSignatureValidatorApproval.sendTransactionAsync(
 | 
						|
                    testValidator.address,
 | 
						|
                    approval,
 | 
						|
                    {
 | 
						|
                        from: signerAddress,
 | 
						|
                    },
 | 
						|
                ),
 | 
						|
            );
 | 
						|
            expect(res.logs.length).to.equal(1);
 | 
						|
            const log = res.logs[0] as LogWithDecodedArgs<TestSignatureValidatorSignatureValidatorApprovalEventArgs>;
 | 
						|
            const logArgs = log.args;
 | 
						|
            expect(logArgs.signerAddress).to.equal(signerAddress);
 | 
						|
            expect(logArgs.validatorAddress).to.equal(testValidator.address);
 | 
						|
            expect(logArgs.approved).to.equal(approval);
 | 
						|
        });
 | 
						|
    });
 | 
						|
});
 | 
						|
// tslint:disable:max-file-line-count
 | 
						|
// tslint:enable:no-unnecessary-type-assertion
 |