From 4874d55d03918b47967024777194d88a5f2bc1fc Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 29 May 2018 16:58:30 -0700 Subject: Initial refactor of order-utils. Move many utils from contracts into this package. --- packages/order-utils/test/order_hash_test.ts | 30 ++++---- packages/order-utils/test/signature_utils_test.ts | 83 +++++++++++++++++++---- 2 files changed, 85 insertions(+), 28 deletions(-) (limited to 'packages/order-utils/test') diff --git a/packages/order-utils/test/order_hash_test.ts b/packages/order-utils/test/order_hash_test.ts index db5489509..7cb87c8ab 100644 --- a/packages/order-utils/test/order_hash_test.ts +++ b/packages/order-utils/test/order_hash_test.ts @@ -1,10 +1,11 @@ import { web3Factory } from '@0xproject/dev-utils'; +import { Order } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; import 'make-promises-safe'; import 'mocha'; -import { constants, getOrderHashHex } from '../src'; +import { constants, orderHashUtils } from '../src'; import { chaiSetup } from './utils/chai_setup'; import { web3Wrapper } from './utils/web3_wrapper'; @@ -14,24 +15,25 @@ const expect = chai.expect; describe('Order hashing', () => { describe('#getOrderHashHex', () => { - const expectedOrderHash = '0x39da987067a3c9e5f1617694f1301326ba8c8b0498ebef5df4863bed394e3c83'; + const expectedOrderHash = '0x367ad7730eb8b5feab8a9c9f47c6fcba77a2d4df125ee6a59cc26ac955710f7e'; const fakeExchangeContractAddress = '0xb69e673309512a9d726f87304c6984054f87a93b'; - const order = { - maker: constants.NULL_ADDRESS, - taker: constants.NULL_ADDRESS, - feeRecipient: constants.NULL_ADDRESS, - makerTokenAddress: constants.NULL_ADDRESS, - takerTokenAddress: constants.NULL_ADDRESS, - exchangeContractAddress: fakeExchangeContractAddress, + const order: Order = { + makerAddress: constants.NULL_ADDRESS, + takerAddress: constants.NULL_ADDRESS, + senderAddress: constants.NULL_ADDRESS, + feeRecipientAddress: constants.NULL_ADDRESS, + makerAssetData: constants.NULL_ADDRESS, + takerAssetData: constants.NULL_ADDRESS, + exchangeAddress: fakeExchangeContractAddress, salt: new BigNumber(0), makerFee: new BigNumber(0), takerFee: new BigNumber(0), - makerTokenAmount: new BigNumber(0), - takerTokenAmount: new BigNumber(0), - expirationUnixTimestampSec: new BigNumber(0), + makerAssetAmount: new BigNumber(0), + takerAssetAmount: new BigNumber(0), + expirationTimeSeconds: new BigNumber(0), }; it('calculates the order hash', async () => { - const orderHash = getOrderHashHex(order); + const orderHash = orderHashUtils.getOrderHashHex(order); expect(orderHash).to.be.equal(expectedOrderHash); }); it('throws a readable error message if taker format is invalid', async () => { @@ -41,7 +43,7 @@ describe('Order hashing', () => { }; const expectedErrorMessage = 'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS'; - expect(() => getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage); + expect(() => orderHashUtils.getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage); }); }); }); diff --git a/packages/order-utils/test/signature_utils_test.ts b/packages/order-utils/test/signature_utils_test.ts index e24fa0ce5..4babd5582 100644 --- a/packages/order-utils/test/signature_utils_test.ts +++ b/packages/order-utils/test/signature_utils_test.ts @@ -7,8 +7,8 @@ import 'make-promises-safe'; import 'mocha'; import * as Sinon from 'sinon'; -import { generatePseudoRandomSalt, isValidOrderHash, isValidSignature, signOrderHashAsync } from '../src'; -import * as signatureUtils from '../src/signature_utils'; +import { ecSignOrderHashAsync, generatePseudoRandomSalt, orderHashUtils } from '../src'; +import { isValidECSignature, isValidSignatureAsync } from '../src/signature_utils'; import { chaiSetup } from './utils/chai_setup'; import { provider, web3Wrapper } from './utils/web3_wrapper'; @@ -20,7 +20,62 @@ const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false; describe('Signature utils', () => { describe('#isValidSignature', () => { - // The Exchange smart contract `isValidSignature` method only validates orderHashes and assumes + let dataHex = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0'; + const ethSignSignature = + '0x031B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254'; + let address = '0x5409ed021d9299bf6814279a6a1411a7e866a631'; + + it("should return false if the data doesn't pertain to the signature & address", async () => { + expect(await isValidSignatureAsync(provider, '0x0', ethSignSignature, address)).to.be.false(); + }); + it("should return false if the address doesn't pertain to the signature & data", async () => { + const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42'; + expect( + await isValidSignatureAsync(provider, dataHex, ethSignSignature, validUnrelatedAddress), + ).to.be.false(); + }); + it("should return false if the signature doesn't pertain to the dataHex & address", async () => { + const signatureArray = ethSignSignature.split(''); + // tslint:disable-next-line:custom-no-magic-numbers + signatureArray[5] = 'C'; // V = 28, instead of 27 + const wrongSignature = signatureArray.join(''); + expect(await isValidSignatureAsync(provider, dataHex, wrongSignature, address)).to.be.false(); + }); + + it('should throw if signatureType is invalid', () => { + const signatureArray = ethSignSignature.split(''); + signatureArray[3] = '9'; // SignatureType w/ index 9 doesn't exist + const signatureWithInvalidType = signatureArray.join(''); + expect(isValidSignatureAsync(provider, dataHex, signatureWithInvalidType, address)).to.be.rejected(); + }); + + it('should return true for a valid Ecrecover (EthSign) signature', async () => { + const isValidSignatureLocal = await isValidSignatureAsync(provider, dataHex, ethSignSignature, address); + expect(isValidSignatureLocal).to.be.true(); + }); + + it('should return true for a valid EIP712 signature', async () => { + dataHex = '0xa1d7403bcbbcd75ec233cfd6584ff8dabed677d0e9bb32c2bea94e9dd8a109da'; + address = '0x6ecbe1db9ef729cbe972c83fb886247691fb6beb'; + const eip712Signature = + '0x041bdde07aac4bf12c12ddbb155919c43eba4146a2cfcf904a862950dbebe332554c6674975603eb5a4eaf8fd7f2e06350267e5b36cda9851a89f8bb49fe2fc9afe2'; + const isValidSignatureLocal = await isValidSignatureAsync(provider, dataHex, eip712Signature, address); + expect(isValidSignatureLocal).to.be.true(); + }); + + it('should return true for a valid Trezor signature', async () => { + dataHex = '0xd0d994e31c88f33fd8a572552a70ed339de579e5ba49ee1d17cc978bbe1cdd21'; + address = '0x6ecbe1db9ef729cbe972c83fb886247691fb6beb'; + const trezorSignature = + '0x051ce4760660e6495b5ae6723087bea073b3a99ce98ea81fdf00c240279c010e63d05b87bc34c4d67d4776e8d5aeb023a67484f4eaf0fd353b40893e5101e845cd99'; + const isValidSignatureLocal = await isValidSignatureAsync(provider, dataHex, trezorSignature, address); + expect(isValidSignatureLocal).to.be.true(); + }); + + // TODO: remaining sigs + }); + describe('#isValidECSignature', () => { + // The Exchange smart contract `isValidECSignature` method only validates orderHashes and assumes // the length of the data is exactly 32 bytes. Thus for these tests, we use data of this size. const dataHex = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0'; const signature = { @@ -30,18 +85,18 @@ describe('Signature utils', () => { }; const address = '0x5409ed021d9299bf6814279a6a1411a7e866a631'; it("should return false if the data doesn't pertain to the signature & address", async () => { - expect(isValidSignature('0x0', signature, address)).to.be.false(); + expect(isValidECSignature('0x0', signature, address)).to.be.false(); }); it("should return false if the address doesn't pertain to the signature & data", async () => { const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42'; - expect(isValidSignature(dataHex, signature, validUnrelatedAddress)).to.be.false(); + expect(isValidECSignature(dataHex, signature, validUnrelatedAddress)).to.be.false(); }); it("should return false if the signature doesn't pertain to the dataHex & address", async () => { const wrongSignature = _.assign({}, signature, { v: 28 }); - expect(isValidSignature(dataHex, wrongSignature, address)).to.be.false(); + expect(isValidECSignature(dataHex, wrongSignature, address)).to.be.false(); }); it('should return true if the signature does pertain to the dataHex & address', async () => { - const isValidSignatureLocal = isValidSignature(dataHex, signature, address); + const isValidSignatureLocal = isValidECSignature(dataHex, signature, address); expect(isValidSignatureLocal).to.be.true(); }); }); @@ -60,20 +115,20 @@ describe('Signature utils', () => { }); describe('#isValidOrderHash', () => { it('returns false if the value is not a hex string', () => { - const isValid = isValidOrderHash('not a hex'); + const isValid = orderHashUtils.isValidOrderHash('not a hex'); expect(isValid).to.be.false(); }); it('returns false if the length is wrong', () => { - const isValid = isValidOrderHash('0xdeadbeef'); + const isValid = orderHashUtils.isValidOrderHash('0xdeadbeef'); expect(isValid).to.be.false(); }); it('returns true if order hash is correct', () => { const orderHashLength = 65; - const isValid = isValidOrderHash('0x' + Array(orderHashLength).join('0')); + const isValid = orderHashUtils.isValidOrderHash('0x' + Array(orderHashLength).join('0')); expect(isValid).to.be.true(); }); }); - describe('#signOrderHashAsync', () => { + describe('#ecSignOrderHashAsync', () => { let stubs: Sinon.SinonStub[] = []; let makerAddress: string; before(async () => { @@ -92,7 +147,7 @@ describe('Signature utils', () => { r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33', s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', }; - const ecSignature = await signOrderHashAsync( + const ecSignature = await ecSignOrderHashAsync( provider, orderHash, makerAddress, @@ -126,7 +181,7 @@ describe('Signature utils', () => { }, }; - const ecSignature = await signOrderHashAsync( + const ecSignature = await ecSignOrderHashAsync( fakeProvider, orderHash, makerAddress, @@ -157,7 +212,7 @@ describe('Signature utils', () => { }, }; - const ecSignature = await signOrderHashAsync( + const ecSignature = await ecSignOrderHashAsync( fakeProvider, orderHash, makerAddress, -- cgit