diff options
Diffstat (limited to 'packages/order-utils')
-rw-r--r-- | packages/order-utils/src/asset_proxy_utils.ts | 20 | ||||
-rw-r--r-- | packages/order-utils/src/signature_utils.ts | 41 | ||||
-rw-r--r-- | packages/order-utils/test/signature_utils_test.ts | 6 |
3 files changed, 34 insertions, 33 deletions
diff --git a/packages/order-utils/src/asset_proxy_utils.ts b/packages/order-utils/src/asset_proxy_utils.ts index 11f81c656..5a084deba 100644 --- a/packages/order-utils/src/asset_proxy_utils.ts +++ b/packages/order-utils/src/asset_proxy_utils.ts @@ -3,8 +3,8 @@ import { BigNumber } from '@0xproject/utils'; import BN = require('bn.js'); import ethUtil = require('ethereumjs-util'); -const ERC20_PROXY_METADATA_BYTE_LENGTH = 21; -const ERC721_PROXY_METADATA_BYTE_LENGTH = 53; +const ERC20_PROXY_METADATA_BYTE_LENGTH = 20; +const ERC721_PROXY_METADATA_BYTE_LENGTH = 52; export const assetProxyUtils = { encodeAssetProxyId(assetProxyId: AssetProxyId): Buffer { @@ -43,7 +43,7 @@ export const assetProxyUtils = { encodeERC20ProxyData(tokenAddress: string): string { const encodedAssetProxyId = assetProxyUtils.encodeAssetProxyId(AssetProxyId.ERC20); const encodedAddress = assetProxyUtils.encodeAddress(tokenAddress); - const encodedMetadata = Buffer.concat([encodedAssetProxyId, encodedAddress]); + const encodedMetadata = Buffer.concat([encodedAddress, encodedAssetProxyId]); const encodedMetadataHex = ethUtil.bufferToHex(encodedMetadata); return encodedMetadataHex; }, @@ -56,7 +56,7 @@ export const assetProxyUtils = { }`, ); } - const encodedAssetProxyId = encodedProxyMetadata.slice(0, 1); + const encodedAssetProxyId = encodedProxyMetadata.slice(-1); const assetProxyId = assetProxyUtils.decodeAssetProxyId(encodedAssetProxyId); if (assetProxyId !== AssetProxyId.ERC20) { throw new Error( @@ -65,7 +65,7 @@ export const assetProxyUtils = { }), but got ${assetProxyId}`, ); } - const encodedTokenAddress = encodedProxyMetadata.slice(1, ERC20_PROXY_METADATA_BYTE_LENGTH); + const encodedTokenAddress = encodedProxyMetadata.slice(0, ERC20_PROXY_METADATA_BYTE_LENGTH); const tokenAddress = assetProxyUtils.decodeAddress(encodedTokenAddress); const erc20ProxyData = { assetProxyId, @@ -77,7 +77,7 @@ export const assetProxyUtils = { const encodedAssetProxyId = assetProxyUtils.encodeAssetProxyId(AssetProxyId.ERC721); const encodedAddress = assetProxyUtils.encodeAddress(tokenAddress); const encodedTokenId = assetProxyUtils.encodeUint256(tokenId); - const encodedMetadata = Buffer.concat([encodedAssetProxyId, encodedAddress, encodedTokenId]); + const encodedMetadata = Buffer.concat([encodedAddress, encodedTokenId, encodedAssetProxyId]); const encodedMetadataHex = ethUtil.bufferToHex(encodedMetadata); return encodedMetadataHex; }, @@ -90,7 +90,7 @@ export const assetProxyUtils = { }`, ); } - const encodedAssetProxyId = encodedProxyMetadata.slice(0, 1); + const encodedAssetProxyId = encodedProxyMetadata.slice(-1); const assetProxyId = assetProxyUtils.decodeAssetProxyId(encodedAssetProxyId); if (assetProxyId !== AssetProxyId.ERC721) { throw new Error( @@ -99,8 +99,8 @@ export const assetProxyUtils = { }), but got ${assetProxyId}`, ); } - const addressOffset = 21; - const encodedTokenAddress = encodedProxyMetadata.slice(1, addressOffset); + const addressOffset = 20; + const encodedTokenAddress = encodedProxyMetadata.slice(0, addressOffset); const tokenAddress = assetProxyUtils.decodeAddress(encodedTokenAddress); const encodedTokenId = encodedProxyMetadata.slice(addressOffset, ERC721_PROXY_METADATA_BYTE_LENGTH); const tokenId = assetProxyUtils.decodeUint256(encodedTokenId); @@ -120,7 +120,7 @@ export const assetProxyUtils = { }`, ); } - const encodedAssetProxyId = encodedProxyMetadata.slice(0, 1); + const encodedAssetProxyId = encodedProxyMetadata.slice(-1); const assetProxyId = assetProxyUtils.decodeAssetProxyId(encodedAssetProxyId); return assetProxyId; }, diff --git a/packages/order-utils/src/signature_utils.ts b/packages/order-utils/src/signature_utils.ts index f1466973c..8e387a6ae 100644 --- a/packages/order-utils/src/signature_utils.ts +++ b/packages/order-utils/src/signature_utils.ts @@ -34,41 +34,40 @@ export async function isValidSignatureAsync( case SignatureType.Invalid: return false; - case SignatureType.Caller: - // HACK: We currently do not "validate" the caller signature type. - // It can only be validated during Exchange contract execution. - throw new Error('Caller signature type cannot be validated off-chain'); - - // TODO: Rename this type to `EthSign` b/c multiple of the signature - // types use ECRecover... - case SignatureType.Ecrecover: { - const ecSignature = parseECSignature(signature); - const prefixedMessageHex = addSignedMessagePrefix(data, MessagePrefixType.EthSign); - return isValidECSignature(prefixedMessageHex, ecSignature, signerAddress); - } - case SignatureType.EIP712: { const ecSignature = parseECSignature(signature); return isValidECSignature(data, ecSignature, signerAddress); } - case SignatureType.Trezor: { - const prefixedMessageHex = addSignedMessagePrefix(data, MessagePrefixType.Trezor); + case SignatureType.EthSign: { const ecSignature = parseECSignature(signature); + const prefixedMessageHex = addSignedMessagePrefix(data, MessagePrefixType.EthSign); return isValidECSignature(prefixedMessageHex, ecSignature, signerAddress); } - // TODO: Rename Contract -> Wallet - case SignatureType.Contract: { + case SignatureType.Caller: + // HACK: We currently do not "validate" the caller signature type. + // It can only be validated during Exchange contract execution. + throw new Error('Caller signature type cannot be validated off-chain'); + + case SignatureType.Wallet: { const signerContract = new ISignerContract(artifacts.ISigner.abi, signerAddress, provider); const isValid = await signerContract.isValidSignature.callAsync(data, signature); return isValid; } + // TODO: Add SignatureType.Validator + case SignatureType.PreSigned: { return isValidPresignedSignatureAsync(provider, data, signature, signerAddress); } + case SignatureType.Trezor: { + const prefixedMessageHex = addSignedMessagePrefix(data, MessagePrefixType.Trezor); + const ecSignature = parseECSignature(signature); + return isValidECSignature(prefixedMessageHex, ecSignature, signerAddress); + } + default: throw new Error(`Unhandled SignatureType: ${signatureTypeIndexIfExists}`); } @@ -205,15 +204,16 @@ function hashTrezorPersonalMessage(message: Buffer): Buffer { } function parseECSignature(signature: string): ECSignature { + assert.isHexString('signature', signature); const signatureTypeIndexIfExists = getSignatureTypeIndexIfExists(signature); - const ecSignatureTypes = [SignatureType.Ecrecover, SignatureType.EIP712, SignatureType.Trezor]; + const ecSignatureTypes = [SignatureType.EthSign, SignatureType.EIP712, SignatureType.Trezor]; const isECSignatureType = _.includes(ecSignatureTypes, signatureTypeIndexIfExists); if (!isECSignatureType) { throw new Error(`Cannot parse non-ECSignature type: ${signatureTypeIndexIfExists}`); } // tslint:disable-next-line:custom-no-magic-numbers - const vrsHex = `0x${signature.substr(4)}`; + const vrsHex = signature.slice(0, -2); const ecSignature = parseSignatureHexAsVRS(vrsHex); return ecSignature; @@ -221,7 +221,8 @@ function parseECSignature(signature: string): ECSignature { function getSignatureTypeIndexIfExists(signature: string): number { const unprefixedSignature = ethUtil.stripHexPrefix(signature); - const signatureTypeHex = unprefixedSignature.substr(0, 2); + // tslint:disable-next-line:custom-no-magic-numbers + const signatureTypeHex = unprefixedSignature.slice(-2); const base = 16; const signatureTypeInt = parseInt(signatureTypeHex, base); return signatureTypeInt; diff --git a/packages/order-utils/test/signature_utils_test.ts b/packages/order-utils/test/signature_utils_test.ts index 321e7313f..d7d895204 100644 --- a/packages/order-utils/test/signature_utils_test.ts +++ b/packages/order-utils/test/signature_utils_test.ts @@ -20,7 +20,7 @@ describe('Signature utils', () => { describe('#isValidSignature', () => { let dataHex = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0'; const ethSignSignature = - '0x031B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254'; + '0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace225403'; let address = '0x5409ed021d9299bf6814279a6a1411a7e866a631'; it("should return false if the data doesn't pertain to the signature & address", async () => { @@ -56,7 +56,7 @@ describe('Signature utils', () => { dataHex = '0xa1d7403bcbbcd75ec233cfd6584ff8dabed677d0e9bb32c2bea94e9dd8a109da'; address = '0x6ecbe1db9ef729cbe972c83fb886247691fb6beb'; const eip712Signature = - '0x041bdde07aac4bf12c12ddbb155919c43eba4146a2cfcf904a862950dbebe332554c6674975603eb5a4eaf8fd7f2e06350267e5b36cda9851a89f8bb49fe2fc9afe2'; + '0x1bdde07aac4bf12c12ddbb155919c43eba4146a2cfcf904a862950dbebe332554c6674975603eb5a4eaf8fd7f2e06350267e5b36cda9851a89f8bb49fe2fc9afe202'; const isValidSignatureLocal = await isValidSignatureAsync(provider, dataHex, eip712Signature, address); expect(isValidSignatureLocal).to.be.true(); }); @@ -65,7 +65,7 @@ describe('Signature utils', () => { dataHex = '0xd0d994e31c88f33fd8a572552a70ed339de579e5ba49ee1d17cc978bbe1cdd21'; address = '0x6ecbe1db9ef729cbe972c83fb886247691fb6beb'; const trezorSignature = - '0x051ce4760660e6495b5ae6723087bea073b3a99ce98ea81fdf00c240279c010e63d05b87bc34c4d67d4776e8d5aeb023a67484f4eaf0fd353b40893e5101e845cd99'; + '0x1ce4760660e6495b5ae6723087bea073b3a99ce98ea81fdf00c240279c010e63d05b87bc34c4d67d4776e8d5aeb023a67484f4eaf0fd353b40893e5101e845cd9908'; const isValidSignatureLocal = await isValidSignatureAsync(provider, dataHex, trezorSignature, address); expect(isValidSignatureLocal).to.be.true(); }); |