diff options
Diffstat (limited to 'packages/order-utils/test')
-rw-r--r-- | packages/order-utils/test/order_hash_test.ts | 47 | ||||
-rw-r--r-- | packages/order-utils/test/signature_utils_test.ts | 135 |
2 files changed, 117 insertions, 65 deletions
diff --git a/packages/order-utils/test/order_hash_test.ts b/packages/order-utils/test/order_hash_test.ts index db5489509..d571fc62a 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,34 +15,50 @@ 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 () => { const orderWithInvalidtakerFormat = { ...order, - taker: (null as any) as string, + takerAddress: (null as any) as string, }; 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); + }); + }); + describe('#isValidOrderHash', () => { + it('returns false if the value is not a hex string', () => { + const isValid = orderHashUtils.isValidOrderHash('not a hex'); + expect(isValid).to.be.false(); + }); + it('returns false if the length is wrong', () => { + const isValid = orderHashUtils.isValidOrderHash('0xdeadbeef'); + expect(isValid).to.be.false(); + }); + it('returns true if order hash is correct', () => { + const orderHashLength = 65; + const isValid = orderHashUtils.isValidOrderHash('0x' + Array(orderHashLength).join('0')); + expect(isValid).to.be.true(); }); }); }); diff --git a/packages/order-utils/test/signature_utils_test.ts b/packages/order-utils/test/signature_utils_test.ts index e24fa0ce5..d7d895204 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, MessagePrefixType, orderHashUtils } from '../src'; +import { isValidECSignature, isValidSignatureAsync } from '../src/signature_utils'; import { chaiSetup } from './utils/chai_setup'; import { provider, web3Wrapper } from './utils/web3_wrapper'; @@ -16,32 +16,85 @@ import { provider, web3Wrapper } from './utils/web3_wrapper'; chaiSetup.configure(); const expect = chai.expect; -const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false; - describe('Signature utils', () => { describe('#isValidSignature', () => { - // The Exchange smart contract `isValidSignature` 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'; + let dataHex = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0'; + const ethSignSignature = + '0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace225403'; + 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 = + '0x1bdde07aac4bf12c12ddbb155919c43eba4146a2cfcf904a862950dbebe332554c6674975603eb5a4eaf8fd7f2e06350267e5b36cda9851a89f8bb49fe2fc9afe202'; + 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 = + '0x1ce4760660e6495b5ae6723087bea073b3a99ce98ea81fdf00c240279c010e63d05b87bc34c4d67d4776e8d5aeb023a67484f4eaf0fd353b40893e5101e845cd9908'; + const isValidSignatureLocal = await isValidSignatureAsync(provider, dataHex, trezorSignature, address); + expect(isValidSignatureLocal).to.be.true(); + }); + + // TODO: remaining sigs + }); + describe('#isValidECSignature', () => { + // TODO: Replace this with a vanilla signature without ANY prefix or modification const signature = { v: 27, - r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33', - s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', + r: '0xaca7da997ad177f040240cdccf6905b71ab16b74434388c3a72f34fd25d64393', + s: '0x46b2bac274ff29b48b3ea6e2d04c1336eaceafda3c53ab483fc3ff12fac3ebf2', }; - const address = '0x5409ed021d9299bf6814279a6a1411a7e866a631'; + const data = '0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad'; + const address = '0x0e5cb767cce09a7f3ca594df118aa519be5e2b5a'; + 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(data, signature, validUnrelatedAddress)).to.be.false(); }); - it("should return false if the signature doesn't pertain to the dataHex & address", async () => { + it("should return false if the signature doesn't pertain to the data & address", async () => { const wrongSignature = _.assign({}, signature, { v: 28 }); - expect(isValidSignature(dataHex, wrongSignature, address)).to.be.false(); + expect(isValidECSignature(data, 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); + it('should return true if the signature does pertain to the data & address', async () => { + const isValidSignatureLocal = isValidECSignature(data, signature, address); expect(isValidSignatureLocal).to.be.true(); }); }); @@ -58,22 +111,7 @@ describe('Signature utils', () => { expect(salt.lessThan(twoPow256)).to.be.true(); }); }); - describe('#isValidOrderHash', () => { - it('returns false if the value is not a hex string', () => { - const isValid = isValidOrderHash('not a hex'); - expect(isValid).to.be.false(); - }); - it('returns false if the length is wrong', () => { - const isValid = 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')); - expect(isValid).to.be.true(); - }); - }); - describe('#signOrderHashAsync', () => { + describe('#ecSignOrderHashAsync', () => { let stubs: Sinon.SinonStub[] = []; let makerAddress: string; before(async () => { @@ -92,12 +130,11 @@ describe('Signature utils', () => { r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33', s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', }; - const ecSignature = await signOrderHashAsync( - provider, - orderHash, - makerAddress, - SHOULD_ADD_PERSONAL_MESSAGE_PREFIX, - ); + const messagePrefixOpts = { + prefixType: MessagePrefixType.EthSign, + shouldAddPrefixBeforeCallingEthSign: false, + }; + const ecSignature = await ecSignOrderHashAsync(provider, orderHash, makerAddress, messagePrefixOpts); expect(ecSignature).to.deep.equal(expectedECSignature); }); it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => { @@ -126,12 +163,11 @@ describe('Signature utils', () => { }, }; - const ecSignature = await signOrderHashAsync( - fakeProvider, - orderHash, - makerAddress, - SHOULD_ADD_PERSONAL_MESSAGE_PREFIX, - ); + const messagePrefixOpts = { + prefixType: MessagePrefixType.EthSign, + shouldAddPrefixBeforeCallingEthSign: false, + }; + const ecSignature = await ecSignOrderHashAsync(fakeProvider, orderHash, makerAddress, messagePrefixOpts); expect(ecSignature).to.deep.equal(expectedECSignature); }); it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => { @@ -157,12 +193,11 @@ describe('Signature utils', () => { }, }; - const ecSignature = await signOrderHashAsync( - fakeProvider, - orderHash, - makerAddress, - SHOULD_ADD_PERSONAL_MESSAGE_PREFIX, - ); + const messagePrefixOpts = { + prefixType: MessagePrefixType.EthSign, + shouldAddPrefixBeforeCallingEthSign: false, + }; + const ecSignature = await ecSignOrderHashAsync(fakeProvider, orderHash, makerAddress, messagePrefixOpts); expect(ecSignature).to.deep.equal(expectedECSignature); }); }); |