From 7dddf2010e16167260f7ffbb7c7d2fd83609d8a0 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 29 May 2017 22:14:18 +0200 Subject: Add getExchangeInstanceOrThrowAsync && getSenderAddressOrThrowAsync --- src/contract_wrappers/exchange_wrapper.ts | 13 +++++++------ src/web3_wrapper.ts | 7 +++++++ 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index f0f153c2b..e18b6d35e 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -16,11 +16,8 @@ export class ExchangeWrapper extends ContractWrapper { assert.doesConformToSchema('ecSignature', ecSignature, ecSignatureSchema); assert.isETHAddressHex('signerAddressHex', signerAddressHex); - const senderAddressIfExists = await this.web3Wrapper.getSenderAddressIfExistsAsync(); - assert.assert(!_.isUndefined(senderAddressIfExists), ZeroExError.USER_HAS_NO_ASSOCIATED_ADDRESSES); - - const contractInstance = await this.instantiateContractIfExistsAsync((ExchangeArtifacts as any)); - const exchangeInstance = contractInstance as ExchangeContract; + const senderAddress = await this.web3Wrapper.getSenderAddressOrThrowAsync(); + const exchangeInstance = await this.getExchangeInstanceOrThrowAsync(); const isValidSignature = await exchangeInstance.isValidSignature.call( signerAddressHex, @@ -29,9 +26,13 @@ export class ExchangeWrapper extends ContractWrapper { ecSignature.r, ecSignature.s, { - from: senderAddressIfExists, + from: senderAddress, }, ); return isValidSignature; } + private async getExchangeInstanceOrThrowAsync(): Promise { + const contractInstance = await this.instantiateContractIfExistsAsync((ExchangeArtifacts as any)); + return contractInstance as ExchangeContract; + } } diff --git a/src/web3_wrapper.ts b/src/web3_wrapper.ts index 3b460e4da..72daabe6f 100644 --- a/src/web3_wrapper.ts +++ b/src/web3_wrapper.ts @@ -2,6 +2,8 @@ import * as _ from 'lodash'; import * as Web3 from 'web3'; import * as BigNumber from 'bignumber.js'; import promisify = require('es6-promisify'); +import {ZeroExError} from "./types"; +import {assert} from "./utils/assert"; export class Web3Wrapper { private web3: Web3; @@ -20,6 +22,11 @@ export class Web3Wrapper { const firstAccount = await this.getFirstAddressIfExistsAsync(); return firstAccount; } + public async getSenderAddressOrThrowAsync(): Promise { + const senderAddressIfExists = await this.getSenderAddressIfExistsAsync(); + assert.assert(!_.isUndefined(senderAddressIfExists), ZeroExError.USER_HAS_NO_ASSOCIATED_ADDRESSES); + return senderAddressIfExists as string; + } public async getFirstAddressIfExistsAsync(): Promise { const addresses = await promisify(this.web3.eth.getAccounts)(); if (_.isEmpty(addresses)) { -- cgit From 96092de5cb97430af35a1c03f22fdc34d7100107 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 29 May 2017 22:30:18 +0200 Subject: Add initial implementation of fillOrderAsync --- src/contract_wrappers/exchange_wrapper.ts | 64 ++++++++++++++++++++++++++++++- src/types.ts | 33 ++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index e18b6d35e..dfa639954 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -1,10 +1,18 @@ import * as _ from 'lodash'; import {Web3Wrapper} from '../web3_wrapper'; -import {ECSignature, ZeroExError, ExchangeContract} from '../types'; +import { + ECSignature, + ExchangeContract, + ExchangeContractErrs, + OrderValues, + OrderAddresses, +} from '../types'; import {assert} from '../utils/assert'; import {ContractWrapper} from './contract_wrapper'; import * as ExchangeArtifacts from '../artifacts/Exchange.json'; import {ecSignatureSchema} from '../schemas/ec_signature_schema'; +import {ContractResponse} from '../types'; +import {constants} from '../utils/constants'; export class ExchangeWrapper extends ContractWrapper { constructor(web3Wrapper: Web3Wrapper) { @@ -31,6 +39,60 @@ export class ExchangeWrapper extends ContractWrapper { ); return isValidSignature; } + public async fillOrderAsync(maker: string, taker: string, makerTokenAddress: string, + takerTokenAddress: string, makerTokenAmount: BigNumber.BigNumber, + takerTokenAmount: BigNumber.BigNumber, makerFee: BigNumber.BigNumber, + takerFee: BigNumber.BigNumber, expirationUnixTimestampSec: BigNumber.BigNumber, + feeRecipient: string, fillAmount: BigNumber.BigNumber, + signatureData: ECSignature, salt: BigNumber.BigNumber) { + const senderAddress = await this.web3Wrapper.getSenderAddressOrThrowAsync(); + const exchangeInstance = await this.getExchangeInstanceOrThrowAsync(); + + taker = taker === '' ? constants.NULL_ADDRESS : taker; + const shouldCheckTransfer = true; + const orderAddresses: OrderAddresses = [ + maker, + taker, + makerTokenAddress, + takerTokenAddress, + feeRecipient, + ]; + const orderValues: OrderValues = [ + makerTokenAmount, + takerTokenAmount, + makerFee, + takerFee, + expirationUnixTimestampSec, + salt, + ]; + const response: ContractResponse = await exchangeInstance.fill( + orderAddresses, + orderValues, + fillAmount, + shouldCheckTransfer, + signatureData.v, + signatureData.r, + signatureData.s, + { + from: senderAddress, + }, + ); + const errEvent = _.find(response.logs, {event: 'LogError'}); + if (!_.isUndefined(errEvent)) { + const errCode = errEvent.args.errorId.toNumber(); + const humanReadableErrMessage = this.exchangeContractErrToMsg[errCode]; + throw new Error(humanReadableErrMessage); + } + return response; + } + private exchangeContractErrToMsg = { + [ExchangeContractErrs.ERROR_FILL_EXPIRED]: 'The order you attempted to fill is expired', + [ExchangeContractErrs.ERROR_CANCEL_EXPIRED]: 'The order you attempted to cancel is expired', + [ExchangeContractErrs.ERROR_FILL_NO_VALUE]: 'This order has already been filled or cancelled', + [ExchangeContractErrs.ERROR_CANCEL_NO_VALUE]: 'This order has already been filled or cancelled', + [ExchangeContractErrs.ERROR_FILL_TRUNCATION]: 'The rounding error was too large when filling this order', + [ExchangeContractErrs.ERROR_FILL_BALANCE_ALLOWANCE]: 'Maker or taker has insufficient balance or allowance', + }; private async getExchangeInstanceOrThrowAsync(): Promise { const contractInstance = await this.instantiateContractIfExistsAsync((ExchangeArtifacts as any)); return contractInstance as ExchangeContract; diff --git a/src/types.ts b/src/types.ts index 3bed01547..0c661915e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -26,8 +26,23 @@ export interface ECSignature { s: string; } +export type OrderAddresses = [string, string, string, string, string]; + +export type OrderValues = [ + BigNumber.BigNumber, BigNumber.BigNumber, BigNumber.BigNumber, + BigNumber.BigNumber, BigNumber.BigNumber, BigNumber.BigNumber +]; + +export interface TxData { + from: string; +} + export interface ExchangeContract { isValidSignature: any; + fill: ( + orderAddresses: OrderAddresses, orderValues: OrderValues, fillAmount: BigNumber.BigNumber, + shouldCheckTransfer: boolean, v: number, r: string, s: string, txData: TxData, + ) => ContractResponse; } export const SolidityTypes = strEnum([ @@ -35,3 +50,21 @@ export const SolidityTypes = strEnum([ 'uint256', ]); export type SolidityTypes = keyof typeof SolidityTypes; + +export enum ExchangeContractErrs { + ERROR_FILL_EXPIRED, // Order has already expired + ERROR_FILL_NO_VALUE, // Order has already been fully filled or cancelled + ERROR_FILL_TRUNCATION, // Rounding error too large + ERROR_FILL_BALANCE_ALLOWANCE, // Insufficient balance or allowance for token transfer + ERROR_CANCEL_EXPIRED, // Order has already expired + ERROR_CANCEL_NO_VALUE, // Order has already been fully filled or cancelled +}; + +export interface ContractResponse { + logs: ContractEvent[]; +} + +export interface ContractEvent { + event: string; + args: any; +} -- cgit From b46ad44856fd3744d90562426356283c90db4fc1 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 29 May 2017 22:34:06 +0200 Subject: Move field declaration to the begining of the class --- src/contract_wrappers/exchange_wrapper.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index dfa639954..ce5a7b8f2 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -15,6 +15,14 @@ import {ContractResponse} from '../types'; import {constants} from '../utils/constants'; export class ExchangeWrapper extends ContractWrapper { + private exchangeContractErrToMsg = { + [ExchangeContractErrs.ERROR_FILL_EXPIRED]: 'The order you attempted to fill is expired', + [ExchangeContractErrs.ERROR_CANCEL_EXPIRED]: 'The order you attempted to cancel is expired', + [ExchangeContractErrs.ERROR_FILL_NO_VALUE]: 'This order has already been filled or cancelled', + [ExchangeContractErrs.ERROR_CANCEL_NO_VALUE]: 'This order has already been filled or cancelled', + [ExchangeContractErrs.ERROR_FILL_TRUNCATION]: 'The rounding error was too large when filling this order', + [ExchangeContractErrs.ERROR_FILL_BALANCE_ALLOWANCE]: 'Maker or taker has insufficient balance or allowance', + }; constructor(web3Wrapper: Web3Wrapper) { super(web3Wrapper); } @@ -85,14 +93,6 @@ export class ExchangeWrapper extends ContractWrapper { } return response; } - private exchangeContractErrToMsg = { - [ExchangeContractErrs.ERROR_FILL_EXPIRED]: 'The order you attempted to fill is expired', - [ExchangeContractErrs.ERROR_CANCEL_EXPIRED]: 'The order you attempted to cancel is expired', - [ExchangeContractErrs.ERROR_FILL_NO_VALUE]: 'This order has already been filled or cancelled', - [ExchangeContractErrs.ERROR_CANCEL_NO_VALUE]: 'This order has already been filled or cancelled', - [ExchangeContractErrs.ERROR_FILL_TRUNCATION]: 'The rounding error was too large when filling this order', - [ExchangeContractErrs.ERROR_FILL_BALANCE_ALLOWANCE]: 'Maker or taker has insufficient balance or allowance', - }; private async getExchangeInstanceOrThrowAsync(): Promise { const contractInstance = await this.instantiateContractIfExistsAsync((ExchangeArtifacts as any)); return contractInstance as ExchangeContract; -- cgit From 7fea7119272a1dd7033719504433357e219847c2 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 29 May 2017 22:42:32 +0200 Subject: Add assertions for parameters --- src/contract_wrappers/exchange_wrapper.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index ce5a7b8f2..691d465cc 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -52,7 +52,21 @@ export class ExchangeWrapper extends ContractWrapper { takerTokenAmount: BigNumber.BigNumber, makerFee: BigNumber.BigNumber, takerFee: BigNumber.BigNumber, expirationUnixTimestampSec: BigNumber.BigNumber, feeRecipient: string, fillAmount: BigNumber.BigNumber, - signatureData: ECSignature, salt: BigNumber.BigNumber) { + ecSignature: ECSignature, salt: BigNumber.BigNumber) { + assert.isBigNumber('salt', salt); + assert.isBigNumber('makerFee', makerFee); + assert.isBigNumber('takerFee', takerFee); + assert.isBigNumber('fillAmount', fillAmount); + assert.isBigNumber('makerTokenAmount', makerTokenAmount); + assert.isBigNumber('takerTokenAmount', takerTokenAmount); + assert.isBigNumber('expirationUnixTimestampSec', expirationUnixTimestampSec); + assert.isETHAddressHex('maker', maker); + assert.isETHAddressHex('taker', taker); + assert.isETHAddressHex('feeRecipient', feeRecipient); + assert.isETHAddressHex('makerTokenAddress', makerTokenAddress); + assert.isETHAddressHex('takerTokenAddress', takerTokenAddress); + assert.doesConformToSchema('ecSignature', ecSignature, ecSignatureSchema); + const senderAddress = await this.web3Wrapper.getSenderAddressOrThrowAsync(); const exchangeInstance = await this.getExchangeInstanceOrThrowAsync(); -- cgit From 9bb738bb2f2b26b61049315ca26a96511460062e Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 29 May 2017 22:45:05 +0200 Subject: Finish ecSignature renaming --- src/contract_wrappers/exchange_wrapper.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index 691d465cc..c129eb367 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -92,9 +92,9 @@ export class ExchangeWrapper extends ContractWrapper { orderValues, fillAmount, shouldCheckTransfer, - signatureData.v, - signatureData.r, - signatureData.s, + ecSignature.v, + ecSignature.r, + ecSignature.s, { from: senderAddress, }, -- cgit From 603a88872d07cb7a380be4eee3111b024bfed886 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 30 May 2017 11:56:23 +0200 Subject: Add Order and SignedOrder types --- src/types.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src') diff --git a/src/types.ts b/src/types.ts index 0c661915e..a14115ef5 100644 --- a/src/types.ts +++ b/src/types.ts @@ -68,3 +68,26 @@ export interface ContractEvent { event: string; args: any; } + +export interface Order { + maker: string; + taker?: string; + + makerFee: BigNumber.BigNumber; + takerFee: BigNumber.BigNumber; + + makerTokenAmount: BigNumber.BigNumber; + takerTokenAmount: BigNumber.BigNumber; + + makerTokenAddress: string; + takerTokenAddress: string; + + salt: BigNumber.BigNumber; + fillAmount: BigNumber.BigNumber; + feeRecipient: string; + expirationUnixTimestampSec: BigNumber.BigNumber; +} + +export interface SignedOrder extends Order { + ecSignature: ECSignature; +} -- cgit From 699e588d1fda7f7e8190a4b3347905964cef2d95 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 30 May 2017 12:00:23 +0200 Subject: Add signedOrderSchema and all subschemas --- src/schemas/signed_order_schema.ts | 50 ++++++++++++++++++++++++++++++++++++++ src/utils/schema_validator.ts | 7 +++++- 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/schemas/signed_order_schema.ts (limited to 'src') diff --git a/src/schemas/signed_order_schema.ts b/src/schemas/signed_order_schema.ts new file mode 100644 index 000000000..b9321cad1 --- /dev/null +++ b/src/schemas/signed_order_schema.ts @@ -0,0 +1,50 @@ +export const addressSchema = { + id: '/addressSchema', + type: 'string', + pattern: '^0[xX][0-9A-Fa-f]{40}$', +}; + +export const bigNumberSchema = { + id: '/bigNumberSchema', + type: 'string', + pattern: '^\d*$', +}; + +export const orderSchema = { + id: '/orderSchema', + properties: { + maker: {$ref: '/addressSchema'}, + taker: {$ref: '/addressSchema'}, + + makerFee: {$ref: '/bigNumberSchema'}, + takerFee: {$ref: '/bigNumberSchema'}, + + makerTokenAmount: {$ref: '/bigNumberSchema'}, + takerTokenAmount: {$ref: '/bigNumberSchema'}, + + makerTokenAddress: {$ref: '/addressSchema'}, + takerTokenAddress: {$ref: '/addressSchema'}, + + salt: {$ref: '/bigNumberSchema'}, + fillAmount: {$ref: '/bigNumberSchema'}, + feeRecipient: {$ref: '/addressSchema'}, + expirationUnixTimestampSec: {$ref: '/bigNumberSchema'}, + }, + required: [ + 'maker', /*'taker',*/ 'makerFee', 'takerFee', 'makerTokenAmount', 'takerTokenAmount', + 'salt', 'fillAmount', 'feeRecipient', 'expirationUnixTimestampSec', + ], + type: 'object', +}; + +export const signedOrderSchema = { + allOf: [ + { $ref: '/orderSchema' }, + { + properties: { + ecSignature: {$ref: '/addressSchema'}, + }, + required: ['ecSignature'], + }, + ], +}; diff --git a/src/utils/schema_validator.ts b/src/utils/schema_validator.ts index 61f4c09c8..0159b6b0b 100644 --- a/src/utils/schema_validator.ts +++ b/src/utils/schema_validator.ts @@ -1,12 +1,17 @@ import {Validator, ValidatorResult} from 'jsonschema'; import {ecSignatureSchema, ecSignatureParameter} from '../schemas/ec_signature_schema'; +import {addressSchema, bigNumberSchema, orderSchema, signedOrderSchema} from '../schemas/signed_order_schema'; export class SchemaValidator { private validator: Validator; constructor() { this.validator = new Validator(); - this.validator.addSchema(ecSignatureParameter, ecSignatureParameter.id); + this.validator.addSchema(orderSchema, orderSchema.id); + this.validator.addSchema(addressSchema, addressSchema.id); + this.validator.addSchema(bigNumberSchema, bigNumberSchema.id); this.validator.addSchema(ecSignatureSchema, ecSignatureSchema.id); + this.validator.addSchema(signedOrderSchema, signedOrderSchema.id); + this.validator.addSchema(ecSignatureParameter, ecSignatureParameter.id); } public validate(instance: object, schema: Schema): ValidatorResult { return this.validator.validate(instance, schema); -- cgit From 95b78d877a1b231d5df2e75447c97b643da4fdaa Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 30 May 2017 12:00:51 +0200 Subject: Add isBoolean assertion --- src/utils/assert.ts | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/utils/assert.ts b/src/utils/assert.ts index 1baf572d1..aeed1c6dc 100644 --- a/src/utils/assert.ts +++ b/src/utils/assert.ts @@ -27,6 +27,9 @@ export const assert = { isNumber(variableName: string, value: number): void { this.assert(_.isFinite(value), this.typeAssertionMessage(variableName, 'number', value)); }, + isBoolean(variableName: string, value: boolean): void { + this.assert(_.isBoolean(value), this.typeAssertionMessage(variableName, 'boolean', value)); + }, doesConformToSchema(variableName: string, value: object, schema: Schema): void { const schemaValidator = new SchemaValidator(); const validationResult = schemaValidator.validate(value, schema); -- cgit From 4b8ff4bf5f18bfb96c50df5928beee3463aca616 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 30 May 2017 12:02:50 +0200 Subject: Add id to signedOrderSchema --- src/schemas/signed_order_schema.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/schemas/signed_order_schema.ts b/src/schemas/signed_order_schema.ts index b9321cad1..fc72476d9 100644 --- a/src/schemas/signed_order_schema.ts +++ b/src/schemas/signed_order_schema.ts @@ -38,6 +38,7 @@ export const orderSchema = { }; export const signedOrderSchema = { + id: '/signedOrderSchema', allOf: [ { $ref: '/orderSchema' }, { -- cgit From 170dd91bfd2896e45a804240938dd8ca8219569e Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 30 May 2017 12:13:30 +0200 Subject: Change BigNumber schema to Number schema --- src/schemas/signed_order_schema.ts | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/schemas/signed_order_schema.ts b/src/schemas/signed_order_schema.ts index fc72476d9..69f33b7bd 100644 --- a/src/schemas/signed_order_schema.ts +++ b/src/schemas/signed_order_schema.ts @@ -4,10 +4,9 @@ export const addressSchema = { pattern: '^0[xX][0-9A-Fa-f]{40}$', }; -export const bigNumberSchema = { - id: '/bigNumberSchema', - type: 'string', - pattern: '^\d*$', +export const numberSchema = { + id: '/numberSchema', + type: 'number', }; export const orderSchema = { @@ -16,19 +15,19 @@ export const orderSchema = { maker: {$ref: '/addressSchema'}, taker: {$ref: '/addressSchema'}, - makerFee: {$ref: '/bigNumberSchema'}, - takerFee: {$ref: '/bigNumberSchema'}, + makerFee: {$ref: '/numberSchema'}, + takerFee: {$ref: '/numberSchema'}, - makerTokenAmount: {$ref: '/bigNumberSchema'}, - takerTokenAmount: {$ref: '/bigNumberSchema'}, + makerTokenAmount: {$ref: '/numberSchema'}, + takerTokenAmount: {$ref: '/numberSchema'}, makerTokenAddress: {$ref: '/addressSchema'}, takerTokenAddress: {$ref: '/addressSchema'}, - salt: {$ref: '/bigNumberSchema'}, - fillAmount: {$ref: '/bigNumberSchema'}, + salt: {$ref: '/numberSchema'}, + fillAmount: {$ref: '/numberSchema'}, feeRecipient: {$ref: '/addressSchema'}, - expirationUnixTimestampSec: {$ref: '/bigNumberSchema'}, + expirationUnixTimestampSec: {$ref: '/numberSchema'}, }, required: [ 'maker', /*'taker',*/ 'makerFee', 'takerFee', 'makerTokenAmount', 'takerTokenAmount', -- cgit From cf63e1d1a6606c1b3ab82d5fec56df8ac4128eea Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 30 May 2017 12:16:33 +0200 Subject: Change BigNumber schema to Number schema --- src/utils/schema_validator.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/utils/schema_validator.ts b/src/utils/schema_validator.ts index 0159b6b0b..5b2c4aaa5 100644 --- a/src/utils/schema_validator.ts +++ b/src/utils/schema_validator.ts @@ -1,14 +1,14 @@ import {Validator, ValidatorResult} from 'jsonschema'; import {ecSignatureSchema, ecSignatureParameter} from '../schemas/ec_signature_schema'; -import {addressSchema, bigNumberSchema, orderSchema, signedOrderSchema} from '../schemas/signed_order_schema'; +import {addressSchema, numberSchema, orderSchema, signedOrderSchema} from '../schemas/signed_order_schema'; export class SchemaValidator { private validator: Validator; constructor() { this.validator = new Validator(); this.validator.addSchema(orderSchema, orderSchema.id); + this.validator.addSchema(numberSchema, numberSchema.id); this.validator.addSchema(addressSchema, addressSchema.id); - this.validator.addSchema(bigNumberSchema, bigNumberSchema.id); this.validator.addSchema(ecSignatureSchema, ecSignatureSchema.id); this.validator.addSchema(signedOrderSchema, signedOrderSchema.id); this.validator.addSchema(ecSignatureParameter, ecSignatureParameter.id); -- cgit From 380c1e1ca521ffad6f4e3832d896bd737f67eab2 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 30 May 2017 12:17:43 +0200 Subject: Make fillOrderAsync accept signedOrder instead of a shit-ton of params --- src/contract_wrappers/exchange_wrapper.ts | 56 ++++++++++++------------------- 1 file changed, 21 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index c129eb367..a4db63b66 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -6,11 +6,13 @@ import { ExchangeContractErrs, OrderValues, OrderAddresses, + SignedOrder, } from '../types'; import {assert} from '../utils/assert'; import {ContractWrapper} from './contract_wrapper'; import * as ExchangeArtifacts from '../artifacts/Exchange.json'; import {ecSignatureSchema} from '../schemas/ec_signature_schema'; +import {signedOrderSchema} from '../schemas/signed_order_schema'; import {ContractResponse} from '../types'; import {constants} from '../utils/constants'; @@ -47,54 +49,38 @@ export class ExchangeWrapper extends ContractWrapper { ); return isValidSignature; } - public async fillOrderAsync(maker: string, taker: string, makerTokenAddress: string, - takerTokenAddress: string, makerTokenAmount: BigNumber.BigNumber, - takerTokenAmount: BigNumber.BigNumber, makerFee: BigNumber.BigNumber, - takerFee: BigNumber.BigNumber, expirationUnixTimestampSec: BigNumber.BigNumber, - feeRecipient: string, fillAmount: BigNumber.BigNumber, - ecSignature: ECSignature, salt: BigNumber.BigNumber) { - assert.isBigNumber('salt', salt); - assert.isBigNumber('makerFee', makerFee); - assert.isBigNumber('takerFee', takerFee); - assert.isBigNumber('fillAmount', fillAmount); - assert.isBigNumber('makerTokenAmount', makerTokenAmount); - assert.isBigNumber('takerTokenAmount', takerTokenAmount); - assert.isBigNumber('expirationUnixTimestampSec', expirationUnixTimestampSec); - assert.isETHAddressHex('maker', maker); - assert.isETHAddressHex('taker', taker); - assert.isETHAddressHex('feeRecipient', feeRecipient); - assert.isETHAddressHex('makerTokenAddress', makerTokenAddress); - assert.isETHAddressHex('takerTokenAddress', takerTokenAddress); - assert.doesConformToSchema('ecSignature', ecSignature, ecSignatureSchema); + public async fillOrderAsync(signedOrder: SignedOrder, shouldCheckTransfer: boolean = true) { + assert.doesConformToSchema('signedOrder', JSON.parse(JSON.stringify(signedOrder)), signedOrderSchema); + assert.isBoolean('shouldCheckTransfer', shouldCheckTransfer); const senderAddress = await this.web3Wrapper.getSenderAddressOrThrowAsync(); const exchangeInstance = await this.getExchangeInstanceOrThrowAsync(); - taker = taker === '' ? constants.NULL_ADDRESS : taker; - const shouldCheckTransfer = true; + const taker = _.isUndefined(signedOrder.taker) ? constants.NULL_ADDRESS : signedOrder.taker; + const orderAddresses: OrderAddresses = [ - maker, + signedOrder.maker, taker, - makerTokenAddress, - takerTokenAddress, - feeRecipient, + signedOrder.makerTokenAddress, + signedOrder.takerTokenAddress, + signedOrder.feeRecipient, ]; const orderValues: OrderValues = [ - makerTokenAmount, - takerTokenAmount, - makerFee, - takerFee, - expirationUnixTimestampSec, - salt, + signedOrder.makerTokenAmount, + signedOrder.takerTokenAmount, + signedOrder.makerFee, + signedOrder.takerFee, + signedOrder.expirationUnixTimestampSec, + signedOrder.salt, ]; const response: ContractResponse = await exchangeInstance.fill( orderAddresses, orderValues, - fillAmount, + signedOrder.fillAmount, shouldCheckTransfer, - ecSignature.v, - ecSignature.r, - ecSignature.s, + signedOrder.ecSignature.v, + signedOrder.ecSignature.r, + signedOrder.ecSignature.s, { from: senderAddress, }, -- cgit From 766d46041ec3958ebd625eb5adbc5b46b329b6d8 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 30 May 2017 12:55:42 +0200 Subject: Add fillAmount parameter --- src/contract_wrappers/exchange_wrapper.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index a4db63b66..141e9502a 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -49,7 +49,8 @@ export class ExchangeWrapper extends ContractWrapper { ); return isValidSignature; } - public async fillOrderAsync(signedOrder: SignedOrder, shouldCheckTransfer: boolean = true) { + public async fillOrderAsync(signedOrder: SignedOrder, fillAmount: BigNumber.BigNumber, + shouldCheckTransfer: boolean = true): Promise { assert.doesConformToSchema('signedOrder', JSON.parse(JSON.stringify(signedOrder)), signedOrderSchema); assert.isBoolean('shouldCheckTransfer', shouldCheckTransfer); @@ -76,7 +77,7 @@ export class ExchangeWrapper extends ContractWrapper { const response: ContractResponse = await exchangeInstance.fill( orderAddresses, orderValues, - signedOrder.fillAmount, + fillAmount, shouldCheckTransfer, signedOrder.ecSignature.v, signedOrder.ecSignature.r, -- cgit From 0b81cd9d78584958d5f33a1a9826a071ed450fc3 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 30 May 2017 12:56:11 +0200 Subject: Fix orderSchema --- src/schemas/signed_order_schema.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/schemas/signed_order_schema.ts b/src/schemas/signed_order_schema.ts index 69f33b7bd..dc7e51e40 100644 --- a/src/schemas/signed_order_schema.ts +++ b/src/schemas/signed_order_schema.ts @@ -6,7 +6,8 @@ export const addressSchema = { export const numberSchema = { id: '/numberSchema', - type: 'number', + type: 'string', + format: '\d+(\.\d+)?', }; export const orderSchema = { @@ -25,13 +26,12 @@ export const orderSchema = { takerTokenAddress: {$ref: '/addressSchema'}, salt: {$ref: '/numberSchema'}, - fillAmount: {$ref: '/numberSchema'}, feeRecipient: {$ref: '/addressSchema'}, expirationUnixTimestampSec: {$ref: '/numberSchema'}, }, required: [ 'maker', /*'taker',*/ 'makerFee', 'takerFee', 'makerTokenAmount', 'takerTokenAmount', - 'salt', 'fillAmount', 'feeRecipient', 'expirationUnixTimestampSec', + 'salt', 'feeRecipient', 'expirationUnixTimestampSec', ], type: 'object', }; @@ -42,7 +42,7 @@ export const signedOrderSchema = { { $ref: '/orderSchema' }, { properties: { - ecSignature: {$ref: '/addressSchema'}, + ecSignature: {$ref: '/ECSignature'}, }, required: ['ecSignature'], }, -- cgit From 76ddd12b4a0fc520b90d9f57f8f6534523d3691e Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 30 May 2017 12:56:28 +0200 Subject: Fix order type --- src/types.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/types.ts b/src/types.ts index a14115ef5..327293cc6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -83,7 +83,6 @@ export interface Order { takerTokenAddress: string; salt: BigNumber.BigNumber; - fillAmount: BigNumber.BigNumber; feeRecipient: string; expirationUnixTimestampSec: BigNumber.BigNumber; } -- cgit From 8c0d783ccc40d5430a5fdc8253968aa457f717bd Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 30 May 2017 14:48:45 +0200 Subject: Add throwErrorLogsAsErrors --- src/contract_wrappers/exchange_wrapper.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index 141e9502a..7a80c5800 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -7,6 +7,7 @@ import { OrderValues, OrderAddresses, SignedOrder, + ContractEvent, } from '../types'; import {assert} from '../utils/assert'; import {ContractWrapper} from './contract_wrapper'; @@ -86,16 +87,19 @@ export class ExchangeWrapper extends ContractWrapper { from: senderAddress, }, ); - const errEvent = _.find(response.logs, {event: 'LogError'}); - if (!_.isUndefined(errEvent)) { - const errCode = errEvent.args.errorId.toNumber(); - const humanReadableErrMessage = this.exchangeContractErrToMsg[errCode]; - throw new Error(humanReadableErrMessage); - } + this.throwErrorLogsAsErrors(response.logs); return response; } private async getExchangeInstanceOrThrowAsync(): Promise { const contractInstance = await this.instantiateContractIfExistsAsync((ExchangeArtifacts as any)); return contractInstance as ExchangeContract; } + private throwErrorLogsAsErrors(logs: ContractEvent[]): void { + const errEvent = _.find(logs, {event: 'LogError'}); + if (!_.isUndefined(errEvent)) { + const errCode = errEvent.args.errorId.toNumber(); + const humanReadableErrMessage = this.exchangeContractErrToMsg[errCode]; + throw new Error(humanReadableErrMessage); + } + } } -- cgit From a4e5ec6c08596d3d59f07aa237887bf27b198e67 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 30 May 2017 15:58:51 +0200 Subject: Add isBigNumber argument assertion --- src/contract_wrappers/exchange_wrapper.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index 66e53a7d4..0749a7e80 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -57,6 +57,7 @@ export class ExchangeWrapper extends ContractWrapper { public async fillOrderAsync(signedOrder: SignedOrder, fillAmount: BigNumber.BigNumber, shouldCheckTransfer: boolean = true): Promise { assert.doesConformToSchema('signedOrder', JSON.parse(JSON.stringify(signedOrder)), signedOrderSchema); + assert.isBigNumber('fillAmount', fillAmount); assert.isBoolean('shouldCheckTransfer', shouldCheckTransfer); const senderAddress = await this.web3Wrapper.getSenderAddressOrThrowAsync(); -- cgit From 843ec2d4cf4bbc9061ba6dc5a09fc6d694c3083a Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 30 May 2017 17:06:38 +0200 Subject: Remove spaces in types --- src/types.ts | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src') diff --git a/src/types.ts b/src/types.ts index 2ada20e3c..dc2a4d848 100644 --- a/src/types.ts +++ b/src/types.ts @@ -81,16 +81,12 @@ export interface ContractEvent { export interface Order { maker: string; taker?: string; - makerFee: BigNumber.BigNumber; takerFee: BigNumber.BigNumber; - makerTokenAmount: BigNumber.BigNumber; takerTokenAmount: BigNumber.BigNumber; - makerTokenAddress: string; takerTokenAddress: string; - salt: BigNumber.BigNumber; feeRecipient: string; expirationUnixTimestampSec: BigNumber.BigNumber; -- cgit From be13cf127c00c762d03c5eaf17a11c2775701530 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 30 May 2017 17:35:17 +0200 Subject: Refactor getOrderHash to accept order as an object --- src/0x.js.ts | 45 ++++++++++++++++----------------------------- 1 file changed, 16 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/0x.js.ts b/src/0x.js.ts index 69c0cc567..47b6679eb 100644 --- a/src/0x.js.ts +++ b/src/0x.js.ts @@ -14,6 +14,8 @@ import {ExchangeWrapper} from './contract_wrappers/exchange_wrapper'; import {TokenRegistryWrapper} from './contract_wrappers/token_registry_wrapper'; import {ecSignatureSchema} from './schemas/ec_signature_schema'; import {SolidityTypes, ECSignature, ZeroExError} from './types'; +import {Order} from './types'; +import {orderSchema} from "./schemas/signed_order_schema"; const MAX_DIGITS_IN_UNSIGNED_256_INT = 78; @@ -24,38 +26,23 @@ export class ZeroEx { /** * Computes the orderHash given the order parameters and returns it as a hex encoded string. */ - public static getOrderHashHex(exchangeContractAddr: string, makerAddr: string, takerAddr: string, - tokenMAddress: string, tokenTAddress: string, feeRecipient: string, - valueM: BigNumber.BigNumber, valueT: BigNumber.BigNumber, - makerFee: BigNumber.BigNumber, takerFee: BigNumber.BigNumber, - expiration: BigNumber.BigNumber, salt: BigNumber.BigNumber): string { - takerAddr = _.isEmpty(takerAddr) ? constants.NULL_ADDRESS : takerAddr ; - assert.isETHAddressHex('exchangeContractAddr', exchangeContractAddr); - assert.isETHAddressHex('makerAddr', makerAddr); - assert.isETHAddressHex('takerAddr', takerAddr); - assert.isETHAddressHex('tokenMAddress', tokenMAddress); - assert.isETHAddressHex('tokenTAddress', tokenTAddress); - assert.isETHAddressHex('feeRecipient', feeRecipient); - assert.isBigNumber('valueM', valueM); - assert.isBigNumber('valueT', valueT); - assert.isBigNumber('makerFee', makerFee); - assert.isBigNumber('takerFee', takerFee); - assert.isBigNumber('expiration', expiration); - assert.isBigNumber('salt', salt); + public static getOrderHashHex(exchangeContractAddr: string, order: Order): string { + assert.doesConformToSchema('order', JSON.parse(JSON.stringify(order)), orderSchema); + const taker = _.isEmpty(order.taker) ? constants.NULL_ADDRESS : order.taker ; const orderParts = [ {value: exchangeContractAddr, type: SolidityTypes.address}, - {value: makerAddr, type: SolidityTypes.address}, - {value: takerAddr, type: SolidityTypes.address}, - {value: tokenMAddress, type: SolidityTypes.address}, - {value: tokenTAddress, type: SolidityTypes.address}, - {value: feeRecipient, type: SolidityTypes.address}, - {value: utils.bigNumberToBN(valueM), type: SolidityTypes.uint256}, - {value: utils.bigNumberToBN(valueT), type: SolidityTypes.uint256}, - {value: utils.bigNumberToBN(makerFee), type: SolidityTypes.uint256}, - {value: utils.bigNumberToBN(takerFee), type: SolidityTypes.uint256}, - {value: utils.bigNumberToBN(expiration), type: SolidityTypes.uint256}, - {value: utils.bigNumberToBN(salt), type: SolidityTypes.uint256}, + {value: order.maker, type: SolidityTypes.address}, + {value: order.taker, type: SolidityTypes.address}, + {value: order.makerTokenAddress, type: SolidityTypes.address}, + {value: order.takerTokenAddress, type: SolidityTypes.address}, + {value: order.feeRecipient, type: SolidityTypes.address}, + {value: utils.bigNumberToBN(order.makerTokenAmount), type: SolidityTypes.uint256}, + {value: utils.bigNumberToBN(order.takerTokenAmount), type: SolidityTypes.uint256}, + {value: utils.bigNumberToBN(order.makerFee), type: SolidityTypes.uint256}, + {value: utils.bigNumberToBN(order.takerFee), type: SolidityTypes.uint256}, + {value: utils.bigNumberToBN(order.expirationUnixTimestampSec), type: SolidityTypes.uint256}, + {value: utils.bigNumberToBN(order.salt), type: SolidityTypes.uint256}, ]; const types = _.map(orderParts, o => o.type); const values = _.map(orderParts, o => o.value); -- cgit From 76a1319387028c3389f10fdb7079aca1d19190ad Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 31 May 2017 14:12:36 +0200 Subject: Set bignumber config --- src/0x.js.ts | 2 ++ src/bignumber_config.ts | 9 +++++++++ 2 files changed, 11 insertions(+) create mode 100644 src/bignumber_config.ts (limited to 'src') diff --git a/src/0x.js.ts b/src/0x.js.ts index 97eb4d126..63a540ad4 100644 --- a/src/0x.js.ts +++ b/src/0x.js.ts @@ -1,5 +1,7 @@ import * as _ from 'lodash'; import * as BigNumber from 'bignumber.js'; +import {setBigNumberConfig} from './bignumber_config'; +setBigNumberConfig(); import * as ethUtil from 'ethereumjs-util'; import contract = require('truffle-contract'); import * as Web3 from 'web3'; diff --git a/src/bignumber_config.ts b/src/bignumber_config.ts new file mode 100644 index 000000000..9641159d0 --- /dev/null +++ b/src/bignumber_config.ts @@ -0,0 +1,9 @@ +import * as BigNumber from 'bignumber.js'; + +export function setBigNumberConfig() { + // By default BigNumber's `toString` method converts to exponential notation if the value has + // more then 20 digits. We want to avoid this behavior, so we set EXPONENTIAL_AT to a high number + BigNumber.config({ + EXPONENTIAL_AT: 1000, + }); +} -- cgit From 722a6ad5dce484ef5875132fd57970390c69e85d Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 31 May 2017 15:56:52 +0200 Subject: Don't return contract response --- src/contract_wrappers/exchange_wrapper.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index 0749a7e80..3f6210894 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -55,7 +55,7 @@ export class ExchangeWrapper extends ContractWrapper { return isValidSignature; } public async fillOrderAsync(signedOrder: SignedOrder, fillAmount: BigNumber.BigNumber, - shouldCheckTransfer: boolean = true): Promise { + shouldCheckTransfer: boolean = true): Promise { assert.doesConformToSchema('signedOrder', JSON.parse(JSON.stringify(signedOrder)), signedOrderSchema); assert.isBigNumber('fillAmount', fillAmount); assert.isBoolean('shouldCheckTransfer', shouldCheckTransfer); @@ -93,7 +93,6 @@ export class ExchangeWrapper extends ContractWrapper { }, ); this.throwErrorLogsAsErrors(response.logs); - return response; } private async getExchangeInstanceOrThrowAsync(): Promise { const contractInstance = await this.instantiateContractIfExistsAsync((ExchangeArtifacts as any)); -- cgit From 1955e90bbbfeb7d2aeebfd84132f684d20e17400 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 31 May 2017 16:15:16 +0200 Subject: Fix linter errors --- src/0x.js.ts | 2 +- src/types.ts | 2 +- src/web3_wrapper.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/0x.js.ts b/src/0x.js.ts index 63a540ad4..25b4af777 100644 --- a/src/0x.js.ts +++ b/src/0x.js.ts @@ -18,7 +18,7 @@ import {ecSignatureSchema} from './schemas/ec_signature_schema'; import {TokenWrapper} from './contract_wrappers/token_wrapper'; import {SolidityTypes, ECSignature, ZeroExError} from './types'; import {Order} from './types'; -import {orderSchema} from "./schemas/signed_order_schema"; +import {orderSchema} from './schemas/signed_order_schema'; const MAX_DIGITS_IN_UNSIGNED_256_INT = 78; diff --git a/src/types.ts b/src/types.ts index 861df3187..b70afe298 100644 --- a/src/types.ts +++ b/src/types.ts @@ -83,7 +83,7 @@ export enum ExchangeContractErrs { ERROR_FILL_BALANCE_ALLOWANCE, // Insufficient balance or allowance for token transfer ERROR_CANCEL_EXPIRED, // Order has already expired ERROR_CANCEL_NO_VALUE, // Order has already been fully filled or cancelled -}; +} export interface ContractResponse { logs: ContractEvent[]; diff --git a/src/web3_wrapper.ts b/src/web3_wrapper.ts index 361f28476..79fd166ec 100644 --- a/src/web3_wrapper.ts +++ b/src/web3_wrapper.ts @@ -2,8 +2,8 @@ import * as _ from 'lodash'; import * as Web3 from 'web3'; import * as BigNumber from 'bignumber.js'; import promisify = require('es6-promisify'); -import {ZeroExError} from "./types"; -import {assert} from "./utils/assert"; +import {ZeroExError} from './types'; +import {assert} from './utils/assert'; export class Web3Wrapper { private web3: Web3; -- cgit From f450f538a0af0b4c85eefdd81c4983f40d230a33 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 1 Jun 2017 11:07:36 +0200 Subject: Add setDefaultAccount --- src/0x.js.ts | 7 +++++++ src/web3_wrapper.ts | 3 +++ 2 files changed, 10 insertions(+) (limited to 'src') diff --git a/src/0x.js.ts b/src/0x.js.ts index 25b4af777..5a0d3033c 100644 --- a/src/0x.js.ts +++ b/src/0x.js.ts @@ -137,6 +137,13 @@ export class ZeroEx { this.tokenRegistry.invalidateContractInstance(); this.token.invalidateContractInstances(); } + + /** + * Sets default account for sending transactions. + */ + public setDefaultAccount(account: string): void { + this.web3Wrapper.setDefaultAccount(account); + } /** * Signs an orderHash and returns it's elliptic curve signature * This method currently supports TestRPC, Geth and Parity above and below V1.6.6 diff --git a/src/web3_wrapper.ts b/src/web3_wrapper.ts index 79fd166ec..70e77dbe3 100644 --- a/src/web3_wrapper.ts +++ b/src/web3_wrapper.ts @@ -17,6 +17,9 @@ export class Web3Wrapper { public isAddress(address: string): boolean { return this.web3.isAddress(address); } + public setDefaultAccount(address: string): void { + this.web3.eth.defaultAccount = address; + } public async getSenderAddressIfExistsAsync(): Promise { const defaultAccount = this.web3.eth.defaultAccount; if (!_.isUndefined(defaultAccount)) { -- cgit From b05e96699f781398c2aac97082c565a531b6e4eb Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 1 Jun 2017 11:08:14 +0200 Subject: Temporarily fix gas extimation --- src/contract_wrappers/exchange_wrapper.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index 3f6210894..754210778 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -80,6 +80,18 @@ export class ExchangeWrapper extends ContractWrapper { signedOrder.expirationUnixTimestampSec, signedOrder.salt, ]; + const gas = await exchangeInstance.fill.estimateGas( + orderAddresses, + orderValues, + fillAmount, + shouldCheckTransfer, + signedOrder.ecSignature.v, + signedOrder.ecSignature.r, + signedOrder.ecSignature.s, + { + from: senderAddress, + }, + ); const response: ContractResponse = await exchangeInstance.fill( orderAddresses, orderValues, @@ -90,6 +102,7 @@ export class ExchangeWrapper extends ContractWrapper { signedOrder.ecSignature.s, { from: senderAddress, + gas, }, ); this.throwErrorLogsAsErrors(response.logs); -- cgit From 81f0414c27bcf64fdc10035951e36bf27f689431 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 1 Jun 2017 11:15:33 +0200 Subject: Remove TxData --- src/types.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src') diff --git a/src/types.ts b/src/types.ts index 8c378816f..cf1376754 100644 --- a/src/types.ts +++ b/src/types.ts @@ -34,15 +34,11 @@ export type OrderValues = [ BigNumber.BigNumber, BigNumber.BigNumber, BigNumber.BigNumber ]; -export interface TxData { - from: string; -} - export interface ExchangeContract { isValidSignature: any; fill: ( orderAddresses: OrderAddresses, orderValues: OrderValues, fillAmount: BigNumber.BigNumber, - shouldCheckTransfer: boolean, v: number, r: string, s: string, txData: TxData, + shouldCheckTransfer: boolean, v: number, r: string, s: string, txData: TxOpts, ) => ContractResponse; } -- cgit From cc4b322a93d659820c4d2a621ebcbf15d32e8929 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 1 Jun 2017 11:34:32 +0200 Subject: Type estimateGas --- src/types.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/types.ts b/src/types.ts index cf1376754..c3cabd4c7 100644 --- a/src/types.ts +++ b/src/types.ts @@ -36,10 +36,12 @@ export type OrderValues = [ export interface ExchangeContract { isValidSignature: any; - fill: ( - orderAddresses: OrderAddresses, orderValues: OrderValues, fillAmount: BigNumber.BigNumber, - shouldCheckTransfer: boolean, v: number, r: string, s: string, txData: TxOpts, - ) => ContractResponse; + fill: { + (orderAddresses: OrderAddresses, orderValues: OrderValues, fillAmount: BigNumber.BigNumber, + shouldCheckTransfer: boolean, v: number, r: string, s: string, txData: TxOpts): ContractResponse; + estimateGas: (orderAddresses: OrderAddresses, orderValues: OrderValues, fillAmount: BigNumber.BigNumber, + shouldCheckTransfer: boolean, v: number, r: string, s: string, txData: TxOpts) => number; + }; } export interface TokenContract { -- cgit From de3a2ff6726351b9d8400a6757a9ce2a18c3c3f6 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 1 Jun 2017 11:40:08 +0200 Subject: Add dirty-chai --- src/globals.d.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/globals.d.ts b/src/globals.d.ts index 0f2fe0f2f..d86f54dfc 100644 --- a/src/globals.d.ts +++ b/src/globals.d.ts @@ -1,4 +1,5 @@ declare module 'chai-bignumber'; +declare module 'dirty-chai'; declare module 'bn.js'; declare module 'request-promise-native'; declare module 'web3-provider-engine'; -- cgit From dbb30aa1dd5db685cf9fea0e23029a77a66290da Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 1 Jun 2017 11:46:57 +0200 Subject: Fix linter errors --- src/globals.d.ts | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/globals.d.ts b/src/globals.d.ts index d86f54dfc..901377bd2 100644 --- a/src/globals.d.ts +++ b/src/globals.d.ts @@ -18,6 +18,10 @@ declare namespace Chai { bignumber: Assertion; // HACK: In order to comply with chai-as-promised we make eventually a `PromisedAssertion` not an `Assertion` eventually: PromisedAssertion; + true: () => void; + false: () => void; + rejected: () => void; + undefined: () => void; } } /* tslint:enable */ -- cgit From 1fe1675726c965b70b118a0f04ad1ddd661ee32e Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 1 Jun 2017 14:11:25 +0200 Subject: make bigNumberConfig a module --- src/0x.js.ts | 6 ++++-- src/bignumber_config.ts | 16 +++++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/0x.js.ts b/src/0x.js.ts index 5a0d3033c..f2093b745 100644 --- a/src/0x.js.ts +++ b/src/0x.js.ts @@ -1,7 +1,6 @@ import * as _ from 'lodash'; import * as BigNumber from 'bignumber.js'; -import {setBigNumberConfig} from './bignumber_config'; -setBigNumberConfig(); +import {bigNumberConfigs} from './bignumber_config'; import * as ethUtil from 'ethereumjs-util'; import contract = require('truffle-contract'); import * as Web3 from 'web3'; @@ -20,6 +19,9 @@ import {SolidityTypes, ECSignature, ZeroExError} from './types'; import {Order} from './types'; import {orderSchema} from './schemas/signed_order_schema'; +// Customize our BigNumber instances +bigNumberConfigs.configure(); + const MAX_DIGITS_IN_UNSIGNED_256_INT = 78; export class ZeroEx { diff --git a/src/bignumber_config.ts b/src/bignumber_config.ts index 9641159d0..9c1715f86 100644 --- a/src/bignumber_config.ts +++ b/src/bignumber_config.ts @@ -1,9 +1,11 @@ import * as BigNumber from 'bignumber.js'; -export function setBigNumberConfig() { - // By default BigNumber's `toString` method converts to exponential notation if the value has - // more then 20 digits. We want to avoid this behavior, so we set EXPONENTIAL_AT to a high number - BigNumber.config({ - EXPONENTIAL_AT: 1000, - }); -} +export const bigNumberConfigs = { + configure() { + // By default BigNumber's `toString` method converts to exponential notation if the value has + // more then 20 digits. We want to avoid this behavior, so we set EXPONENTIAL_AT to a high number + BigNumber.config({ + EXPONENTIAL_AT: 1000, + }); + }, +}; -- cgit From 0991191a9b6c00fac80cd9f5ffa8e76c62f82eb5 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 1 Jun 2017 14:43:14 +0200 Subject: move external imports to top --- src/0x.js.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/0x.js.ts b/src/0x.js.ts index f2093b745..e5eb6b520 100644 --- a/src/0x.js.ts +++ b/src/0x.js.ts @@ -5,12 +5,12 @@ import * as ethUtil from 'ethereumjs-util'; import contract = require('truffle-contract'); import * as Web3 from 'web3'; import * as ethABI from 'ethereumjs-abi'; +import findVersions = require('find-versions'); +import compareVersions = require('compare-versions'); import {Web3Wrapper} from './web3_wrapper'; import {constants} from './utils/constants'; import {utils} from './utils/utils'; import {assert} from './utils/assert'; -import findVersions = require('find-versions'); -import compareVersions = require('compare-versions'); import {ExchangeWrapper} from './contract_wrappers/exchange_wrapper'; import {TokenRegistryWrapper} from './contract_wrappers/token_registry_wrapper'; import {ecSignatureSchema} from './schemas/ec_signature_schema'; -- cgit From c74b16eda9465104e1969b1635ac826835d203eb Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 1 Jun 2017 14:46:09 +0200 Subject: Add convertToJSONSchemaCompatibleObject method --- src/0x.js.ts | 5 ++++- src/contract_wrappers/exchange_wrapper.ts | 5 ++++- src/utils/schema_validator.ts | 7 +++++++ 3 files changed, 15 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/0x.js.ts b/src/0x.js.ts index e5eb6b520..92a5d2c54 100644 --- a/src/0x.js.ts +++ b/src/0x.js.ts @@ -11,6 +11,7 @@ import {Web3Wrapper} from './web3_wrapper'; import {constants} from './utils/constants'; import {utils} from './utils/utils'; import {assert} from './utils/assert'; +import {SchemaValidator} from './utils/schema_validator'; import {ExchangeWrapper} from './contract_wrappers/exchange_wrapper'; import {TokenRegistryWrapper} from './contract_wrappers/token_registry_wrapper'; import {ecSignatureSchema} from './schemas/ec_signature_schema'; @@ -33,7 +34,9 @@ export class ZeroEx { * Computes the orderHash given the order parameters and returns it as a hex encoded string. */ public static getOrderHashHex(exchangeContractAddr: string, order: Order): string { - assert.doesConformToSchema('order', JSON.parse(JSON.stringify(order)), orderSchema); + assert.doesConformToSchema('order', + SchemaValidator.convertToJSONSchemaCompatibleObject(order as object), + orderSchema); const taker = _.isEmpty(order.taker) ? constants.NULL_ADDRESS : order.taker ; const orderParts = [ diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index 754210778..59e6c755e 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -14,6 +14,7 @@ import {ContractWrapper} from './contract_wrapper'; import * as ExchangeArtifacts from '../artifacts/Exchange.json'; import {ecSignatureSchema} from '../schemas/ec_signature_schema'; import {signedOrderSchema} from '../schemas/signed_order_schema'; +import {SchemaValidator} from '../utils/schema_validator'; import {ContractResponse} from '../types'; import {constants} from '../utils/constants'; @@ -56,7 +57,9 @@ export class ExchangeWrapper extends ContractWrapper { } public async fillOrderAsync(signedOrder: SignedOrder, fillAmount: BigNumber.BigNumber, shouldCheckTransfer: boolean = true): Promise { - assert.doesConformToSchema('signedOrder', JSON.parse(JSON.stringify(signedOrder)), signedOrderSchema); + assert.doesConformToSchema('signedOrder', + SchemaValidator.convertToJSONSchemaCompatibleObject(signedOrder as object), + signedOrderSchema); assert.isBigNumber('fillAmount', fillAmount); assert.isBoolean('shouldCheckTransfer', shouldCheckTransfer); diff --git a/src/utils/schema_validator.ts b/src/utils/schema_validator.ts index cf45d0343..9ff7259d9 100644 --- a/src/utils/schema_validator.ts +++ b/src/utils/schema_validator.ts @@ -5,6 +5,13 @@ import {tokenSchema} from '../schemas/token_schema'; export class SchemaValidator { private validator: Validator; + // In order to validate a complex JS object using jsonschema, we must replace any complex + // sub-types (e.g BigNumber) with a simpler string represenation. Since BigNumber and other + // complex types implement the `toString` method, we can stringify the object and + // then parse it. The resultant object can then be checked using jsonschema. + public static convertToJSONSchemaCompatibleObject(obj: object): object { + return JSON.parse(JSON.stringify(obj)); + } constructor() { this.validator = new Validator(); this.validator.addSchema(tokenSchema, tokenSchema.id); -- cgit From 84f8570e78ef7637bbeb39d861342af9dda45943 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 1 Jun 2017 14:46:24 +0200 Subject: Fix types hell with, chai and chai-as-promised --- src/globals.d.ts | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src') diff --git a/src/globals.d.ts b/src/globals.d.ts index 901377bd2..d86f54dfc 100644 --- a/src/globals.d.ts +++ b/src/globals.d.ts @@ -18,10 +18,6 @@ declare namespace Chai { bignumber: Assertion; // HACK: In order to comply with chai-as-promised we make eventually a `PromisedAssertion` not an `Assertion` eventually: PromisedAssertion; - true: () => void; - false: () => void; - rejected: () => void; - undefined: () => void; } } /* tslint:enable */ -- cgit From 1668a085049d3b065c47709ef0018a66f637b992 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 1 Jun 2017 14:59:03 +0200 Subject: rename signed_order_schema to order_schemas --- src/0x.js.ts | 2 +- src/contract_wrappers/exchange_wrapper.ts | 2 +- src/schemas/order_schemas.ts | 50 +++++++++++++++++++++++++++++++ src/schemas/signed_order_schema.ts | 50 ------------------------------- src/utils/schema_validator.ts | 2 +- 5 files changed, 53 insertions(+), 53 deletions(-) create mode 100644 src/schemas/order_schemas.ts delete mode 100644 src/schemas/signed_order_schema.ts (limited to 'src') diff --git a/src/0x.js.ts b/src/0x.js.ts index 92a5d2c54..bf56d5f8d 100644 --- a/src/0x.js.ts +++ b/src/0x.js.ts @@ -18,7 +18,7 @@ import {ecSignatureSchema} from './schemas/ec_signature_schema'; import {TokenWrapper} from './contract_wrappers/token_wrapper'; import {SolidityTypes, ECSignature, ZeroExError} from './types'; import {Order} from './types'; -import {orderSchema} from './schemas/signed_order_schema'; +import {orderSchema} from './schemas/order_schemas'; // Customize our BigNumber instances bigNumberConfigs.configure(); diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index 59e6c755e..ad2573c6b 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -13,7 +13,7 @@ import {assert} from '../utils/assert'; import {ContractWrapper} from './contract_wrapper'; import * as ExchangeArtifacts from '../artifacts/Exchange.json'; import {ecSignatureSchema} from '../schemas/ec_signature_schema'; -import {signedOrderSchema} from '../schemas/signed_order_schema'; +import {signedOrderSchema} from '../schemas/order_schemas'; import {SchemaValidator} from '../utils/schema_validator'; import {ContractResponse} from '../types'; import {constants} from '../utils/constants'; diff --git a/src/schemas/order_schemas.ts b/src/schemas/order_schemas.ts new file mode 100644 index 000000000..dc7e51e40 --- /dev/null +++ b/src/schemas/order_schemas.ts @@ -0,0 +1,50 @@ +export const addressSchema = { + id: '/addressSchema', + type: 'string', + pattern: '^0[xX][0-9A-Fa-f]{40}$', +}; + +export const numberSchema = { + id: '/numberSchema', + type: 'string', + format: '\d+(\.\d+)?', +}; + +export const orderSchema = { + id: '/orderSchema', + properties: { + maker: {$ref: '/addressSchema'}, + taker: {$ref: '/addressSchema'}, + + makerFee: {$ref: '/numberSchema'}, + takerFee: {$ref: '/numberSchema'}, + + makerTokenAmount: {$ref: '/numberSchema'}, + takerTokenAmount: {$ref: '/numberSchema'}, + + makerTokenAddress: {$ref: '/addressSchema'}, + takerTokenAddress: {$ref: '/addressSchema'}, + + salt: {$ref: '/numberSchema'}, + feeRecipient: {$ref: '/addressSchema'}, + expirationUnixTimestampSec: {$ref: '/numberSchema'}, + }, + required: [ + 'maker', /*'taker',*/ 'makerFee', 'takerFee', 'makerTokenAmount', 'takerTokenAmount', + 'salt', 'feeRecipient', 'expirationUnixTimestampSec', + ], + type: 'object', +}; + +export const signedOrderSchema = { + id: '/signedOrderSchema', + allOf: [ + { $ref: '/orderSchema' }, + { + properties: { + ecSignature: {$ref: '/ECSignature'}, + }, + required: ['ecSignature'], + }, + ], +}; diff --git a/src/schemas/signed_order_schema.ts b/src/schemas/signed_order_schema.ts deleted file mode 100644 index dc7e51e40..000000000 --- a/src/schemas/signed_order_schema.ts +++ /dev/null @@ -1,50 +0,0 @@ -export const addressSchema = { - id: '/addressSchema', - type: 'string', - pattern: '^0[xX][0-9A-Fa-f]{40}$', -}; - -export const numberSchema = { - id: '/numberSchema', - type: 'string', - format: '\d+(\.\d+)?', -}; - -export const orderSchema = { - id: '/orderSchema', - properties: { - maker: {$ref: '/addressSchema'}, - taker: {$ref: '/addressSchema'}, - - makerFee: {$ref: '/numberSchema'}, - takerFee: {$ref: '/numberSchema'}, - - makerTokenAmount: {$ref: '/numberSchema'}, - takerTokenAmount: {$ref: '/numberSchema'}, - - makerTokenAddress: {$ref: '/addressSchema'}, - takerTokenAddress: {$ref: '/addressSchema'}, - - salt: {$ref: '/numberSchema'}, - feeRecipient: {$ref: '/addressSchema'}, - expirationUnixTimestampSec: {$ref: '/numberSchema'}, - }, - required: [ - 'maker', /*'taker',*/ 'makerFee', 'takerFee', 'makerTokenAmount', 'takerTokenAmount', - 'salt', 'feeRecipient', 'expirationUnixTimestampSec', - ], - type: 'object', -}; - -export const signedOrderSchema = { - id: '/signedOrderSchema', - allOf: [ - { $ref: '/orderSchema' }, - { - properties: { - ecSignature: {$ref: '/ECSignature'}, - }, - required: ['ecSignature'], - }, - ], -}; diff --git a/src/utils/schema_validator.ts b/src/utils/schema_validator.ts index 9ff7259d9..db8a960ba 100644 --- a/src/utils/schema_validator.ts +++ b/src/utils/schema_validator.ts @@ -1,6 +1,6 @@ import {Validator, ValidatorResult} from 'jsonschema'; import {ecSignatureSchema, ecSignatureParameter} from '../schemas/ec_signature_schema'; -import {addressSchema, numberSchema, orderSchema, signedOrderSchema} from '../schemas/signed_order_schema'; +import {addressSchema, numberSchema, orderSchema, signedOrderSchema} from '../schemas/order_schemas'; import {tokenSchema} from '../schemas/token_schema'; export class SchemaValidator { -- cgit From 88316455b74d2ecde1da55bf2bb36b6c9b46bcb1 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 1 Jun 2017 15:10:22 +0200 Subject: Make taker required on Order object and expect NULL_ADDRESS from 0x.js --- src/0x.js.ts | 3 ++- src/contract_wrappers/exchange_wrapper.ts | 4 +--- src/schemas/order_schemas.ts | 2 +- src/types.ts | 4 ++-- 4 files changed, 6 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/0x.js.ts b/src/0x.js.ts index bf56d5f8d..1a46fe9a5 100644 --- a/src/0x.js.ts +++ b/src/0x.js.ts @@ -26,6 +26,8 @@ bigNumberConfigs.configure(); const MAX_DIGITS_IN_UNSIGNED_256_INT = 78; export class ZeroEx { + public static NULL_ADDRESS = constants.NULL_ADDRESS; + public exchange: ExchangeWrapper; public tokenRegistry: TokenRegistryWrapper; public token: TokenWrapper; @@ -37,7 +39,6 @@ export class ZeroEx { assert.doesConformToSchema('order', SchemaValidator.convertToJSONSchemaCompatibleObject(order as object), orderSchema); - const taker = _.isEmpty(order.taker) ? constants.NULL_ADDRESS : order.taker ; const orderParts = [ {value: exchangeContractAddr, type: SolidityTypes.address}, diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index ad2573c6b..d1763e307 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -66,11 +66,9 @@ export class ExchangeWrapper extends ContractWrapper { const senderAddress = await this.web3Wrapper.getSenderAddressOrThrowAsync(); const exchangeInstance = await this.getExchangeInstanceOrThrowAsync(); - const taker = _.isUndefined(signedOrder.taker) ? constants.NULL_ADDRESS : signedOrder.taker; - const orderAddresses: OrderAddresses = [ signedOrder.maker, - taker, + signedOrder.taker, signedOrder.makerTokenAddress, signedOrder.takerTokenAddress, signedOrder.feeRecipient, diff --git a/src/schemas/order_schemas.ts b/src/schemas/order_schemas.ts index dc7e51e40..72012dc26 100644 --- a/src/schemas/order_schemas.ts +++ b/src/schemas/order_schemas.ts @@ -30,7 +30,7 @@ export const orderSchema = { expirationUnixTimestampSec: {$ref: '/numberSchema'}, }, required: [ - 'maker', /*'taker',*/ 'makerFee', 'takerFee', 'makerTokenAmount', 'takerTokenAmount', + 'maker', 'taker', 'makerFee', 'takerFee', 'makerTokenAmount', 'takerTokenAmount', 'salt', 'feeRecipient', 'expirationUnixTimestampSec', ], type: 'object', diff --git a/src/types.ts b/src/types.ts index c3cabd4c7..7d668e78a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -31,7 +31,7 @@ export type OrderAddresses = [string, string, string, string, string]; export type OrderValues = [ BigNumber.BigNumber, BigNumber.BigNumber, BigNumber.BigNumber, - BigNumber.BigNumber, BigNumber.BigNumber, BigNumber.BigNumber + BigNumber.BigNumber, BigNumber.BigNumber, BigNumber.BigNumber, ]; export interface ExchangeContract { @@ -90,7 +90,7 @@ export interface ContractEvent { export interface Order { maker: string; - taker?: string; + taker: string; makerFee: BigNumber.BigNumber; takerFee: BigNumber.BigNumber; makerTokenAmount: BigNumber.BigNumber; -- cgit From 07cdfa655be81862f7ff40fe5ac6fdb38d780370 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 1 Jun 2017 15:12:27 +0200 Subject: Add FILL_AMOUNT_IS_ZERO check --- src/contract_wrappers/exchange_wrapper.ts | 9 +++++++++ src/types.ts | 5 +++++ 2 files changed, 14 insertions(+) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index d1763e307..7a5b6ac8c 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -4,6 +4,7 @@ import { ECSignature, ExchangeContract, ExchangeContractErrs, + FillOrderValidationErrs, OrderValues, OrderAddresses, SignedOrder, @@ -66,6 +67,8 @@ export class ExchangeWrapper extends ContractWrapper { const senderAddress = await this.web3Wrapper.getSenderAddressOrThrowAsync(); const exchangeInstance = await this.getExchangeInstanceOrThrowAsync(); + this.validateFillOrder(signedOrder, fillAmount, senderAddress, shouldCheckTransfer); + const orderAddresses: OrderAddresses = [ signedOrder.maker, signedOrder.taker, @@ -108,6 +111,12 @@ export class ExchangeWrapper extends ContractWrapper { ); this.throwErrorLogsAsErrors(response.logs); } + private validateFillOrder(signedOrder: SignedOrder, fillAmount: BigNumber.BigNumber, senderAddress: string, + shouldCheckTransfer: boolean = true) { + if (fillAmount.eq(0)) { + throw new Error(FillOrderValidationErrs.FILL_AMOUNT_IS_ZERO); + } + } private async getExchangeInstanceOrThrowAsync(): Promise { const contractInstance = await this.instantiateContractIfExistsAsync((ExchangeArtifacts as any)); return contractInstance as ExchangeContract; diff --git a/src/types.ts b/src/types.ts index 7d668e78a..d9ed0b6bf 100644 --- a/src/types.ts +++ b/src/types.ts @@ -79,6 +79,11 @@ export enum ExchangeContractErrs { ERROR_CANCEL_NO_VALUE, // Order has already been fully filled or cancelled } +export const FillOrderValidationErrs = strEnum([ + 'FILL_AMOUNT_IS_ZERO', +]); +export type FillOrderValidationErrs = keyof typeof FillOrderValidationErrs; + export interface ContractResponse { logs: ContractEvent[]; } -- cgit From d5d20db439a4a6fe913462bd216a776cc4300450 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 1 Jun 2017 15:18:13 +0200 Subject: Add NOT_A_TAKER check --- src/contract_wrappers/exchange_wrapper.ts | 3 +++ src/types.ts | 1 + 2 files changed, 4 insertions(+) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index 7a5b6ac8c..e53754e07 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -116,6 +116,9 @@ export class ExchangeWrapper extends ContractWrapper { if (fillAmount.eq(0)) { throw new Error(FillOrderValidationErrs.FILL_AMOUNT_IS_ZERO); } + if (signedOrder.taker !== constants.NULL_ADDRESS && signedOrder.taker !== senderAddress) { + throw new Error(FillOrderValidationErrs.NOT_A_TAKER); + } } private async getExchangeInstanceOrThrowAsync(): Promise { const contractInstance = await this.instantiateContractIfExistsAsync((ExchangeArtifacts as any)); diff --git a/src/types.ts b/src/types.ts index d9ed0b6bf..d6970bc0b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -81,6 +81,7 @@ export enum ExchangeContractErrs { export const FillOrderValidationErrs = strEnum([ 'FILL_AMOUNT_IS_ZERO', + 'NOT_A_TAKER', ]); export type FillOrderValidationErrs = keyof typeof FillOrderValidationErrs; -- cgit From d8e35c364ea94b606810b340fb02d8706e257c3c Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 1 Jun 2017 15:46:27 +0200 Subject: Add EXPIRED test --- src/contract_wrappers/exchange_wrapper.ts | 3 +++ src/types.ts | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index e53754e07..88b0fa913 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -119,6 +119,9 @@ export class ExchangeWrapper extends ContractWrapper { if (signedOrder.taker !== constants.NULL_ADDRESS && signedOrder.taker !== senderAddress) { throw new Error(FillOrderValidationErrs.NOT_A_TAKER); } + if (signedOrder.expirationUnixTimestampSec.lessThan(Date.now() / 1000)) { + throw new Error(FillOrderValidationErrs.EXPIRED); + } } private async getExchangeInstanceOrThrowAsync(): Promise { const contractInstance = await this.instantiateContractIfExistsAsync((ExchangeArtifacts as any)); diff --git a/src/types.ts b/src/types.ts index d6970bc0b..6d4166013 100644 --- a/src/types.ts +++ b/src/types.ts @@ -31,7 +31,7 @@ export type OrderAddresses = [string, string, string, string, string]; export type OrderValues = [ BigNumber.BigNumber, BigNumber.BigNumber, BigNumber.BigNumber, - BigNumber.BigNumber, BigNumber.BigNumber, BigNumber.BigNumber, + BigNumber.BigNumber, BigNumber.BigNumber, BigNumber.BigNumber ]; export interface ExchangeContract { @@ -82,6 +82,7 @@ export enum ExchangeContractErrs { export const FillOrderValidationErrs = strEnum([ 'FILL_AMOUNT_IS_ZERO', 'NOT_A_TAKER', + 'EXPIRED', ]); export type FillOrderValidationErrs = keyof typeof FillOrderValidationErrs; -- cgit From 6a57c42e253a52a449cae8a5c6565276cb01a86c Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 1 Jun 2017 15:51:45 +0200 Subject: Rename ExchangeContractErrs to ExchangeContractErrCodes --- src/contract_wrappers/exchange_wrapper.ts | 18 +++++++++--------- src/types.ts | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index d1763e307..1311730a0 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -3,7 +3,7 @@ import {Web3Wrapper} from '../web3_wrapper'; import { ECSignature, ExchangeContract, - ExchangeContractErrs, + ExchangeContractErrCodes, OrderValues, OrderAddresses, SignedOrder, @@ -19,13 +19,13 @@ import {ContractResponse} from '../types'; import {constants} from '../utils/constants'; export class ExchangeWrapper extends ContractWrapper { - private exchangeContractErrToMsg = { - [ExchangeContractErrs.ERROR_FILL_EXPIRED]: 'The order you attempted to fill is expired', - [ExchangeContractErrs.ERROR_CANCEL_EXPIRED]: 'The order you attempted to cancel is expired', - [ExchangeContractErrs.ERROR_FILL_NO_VALUE]: 'This order has already been filled or cancelled', - [ExchangeContractErrs.ERROR_CANCEL_NO_VALUE]: 'This order has already been filled or cancelled', - [ExchangeContractErrs.ERROR_FILL_TRUNCATION]: 'The rounding error was too large when filling this order', - [ExchangeContractErrs.ERROR_FILL_BALANCE_ALLOWANCE]: 'Maker or taker has insufficient balance or allowance', + private exchangeContractErrCodesToMsg = { + [ExchangeContractErrCodes.ERROR_FILL_EXPIRED]: 'The order you attempted to fill is expired', + [ExchangeContractErrCodes.ERROR_CANCEL_EXPIRED]: 'The order you attempted to cancel is expired', + [ExchangeContractErrCodes.ERROR_FILL_NO_VALUE]: 'This order has already been filled or cancelled', + [ExchangeContractErrCodes.ERROR_CANCEL_NO_VALUE]: 'This order has already been filled or cancelled', + [ExchangeContractErrCodes.ERROR_FILL_TRUNCATION]: 'The rounding error was too large when filling this order', + [ExchangeContractErrCodes.ERROR_FILL_BALANCE_ALLOWANCE]: 'Maker or taker has insufficient balance or allowance', }; private exchangeContractIfExists?: ExchangeContract; constructor(web3Wrapper: Web3Wrapper) { @@ -116,7 +116,7 @@ export class ExchangeWrapper extends ContractWrapper { const errEvent = _.find(logs, {event: 'LogError'}); if (!_.isUndefined(errEvent)) { const errCode = errEvent.args.errorId.toNumber(); - const humanReadableErrMessage = this.exchangeContractErrToMsg[errCode]; + const humanReadableErrMessage = this.exchangeContractErrCodesToMsg[errCode]; throw new Error(humanReadableErrMessage); } } diff --git a/src/types.ts b/src/types.ts index 7d668e78a..18de4d27e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -70,7 +70,7 @@ export const SolidityTypes = strEnum([ ]); export type SolidityTypes = keyof typeof SolidityTypes; -export enum ExchangeContractErrs { +export enum ExchangeContractErrCodes { ERROR_FILL_EXPIRED, // Order has already expired ERROR_FILL_NO_VALUE, // Order has already been fully filled or cancelled ERROR_FILL_TRUNCATION, // Rounding error too large -- cgit From a685d7604fcd0854ad49df762c4ed5a51cc86065 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 1 Jun 2017 16:02:44 +0200 Subject: fix formatting --- src/types.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/types.ts b/src/types.ts index 992bb4b00..c3a19d3b6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -29,10 +29,8 @@ export interface ECSignature { export type OrderAddresses = [string, string, string, string, string]; -export type OrderValues = [ - BigNumber.BigNumber, BigNumber.BigNumber, BigNumber.BigNumber, - BigNumber.BigNumber, BigNumber.BigNumber, BigNumber.BigNumber -]; +export type OrderValues = [BigNumber.BigNumber, BigNumber.BigNumber, BigNumber.BigNumber, + BigNumber.BigNumber, BigNumber.BigNumber, BigNumber.BigNumber]; export interface ExchangeContract { isValidSignature: any; -- cgit From 88a70afa70f84efc866ff53121d05a6d8d77bff8 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 1 Jun 2017 16:03:09 +0200 Subject: Add ExchangeContractErrs string enum --- src/contract_wrappers/exchange_wrapper.ts | 17 +++++++++-------- src/types.ts | 8 ++++++++ 2 files changed, 17 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index bf3f10e28..1232b969b 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -4,6 +4,7 @@ import { ECSignature, ExchangeContract, ExchangeContractErrCodes, + ExchangeContractErrs, FillOrderValidationErrs, OrderValues, OrderAddresses, @@ -21,12 +22,12 @@ import {constants} from '../utils/constants'; export class ExchangeWrapper extends ContractWrapper { private exchangeContractErrCodesToMsg = { - [ExchangeContractErrCodes.ERROR_FILL_EXPIRED]: 'The order you attempted to fill is expired', - [ExchangeContractErrCodes.ERROR_CANCEL_EXPIRED]: 'The order you attempted to cancel is expired', - [ExchangeContractErrCodes.ERROR_FILL_NO_VALUE]: 'This order has already been filled or cancelled', - [ExchangeContractErrCodes.ERROR_CANCEL_NO_VALUE]: 'This order has already been filled or cancelled', - [ExchangeContractErrCodes.ERROR_FILL_TRUNCATION]: 'The rounding error was too large when filling this order', - [ExchangeContractErrCodes.ERROR_FILL_BALANCE_ALLOWANCE]: 'Maker or taker has insufficient balance or allowance', + [ExchangeContractErrCodes.ERROR_FILL_EXPIRED]: ExchangeContractErrs.ORDER_EXPIRED, + [ExchangeContractErrCodes.ERROR_CANCEL_EXPIRED]: ExchangeContractErrs.ORDER_EXPIRED, + [ExchangeContractErrCodes.ERROR_FILL_NO_VALUE]: ExchangeContractErrs.ORDER_REMAINING_FILL_AMOUNT_ZERO, + [ExchangeContractErrCodes.ERROR_CANCEL_NO_VALUE]: ExchangeContractErrs.ORDER_REMAINING_FILL_AMOUNT_ZERO, + [ExchangeContractErrCodes.ERROR_FILL_TRUNCATION]: ExchangeContractErrs.ORDER_ROUNDING_ERROR, + [ExchangeContractErrCodes.ERROR_FILL_BALANCE_ALLOWANCE]: ExchangeContractErrs.ORDER_BALANCE_ALLOWANCE_ERROR, }; private exchangeContractIfExists?: ExchangeContract; constructor(web3Wrapper: Web3Wrapper) { @@ -131,8 +132,8 @@ export class ExchangeWrapper extends ContractWrapper { const errEvent = _.find(logs, {event: 'LogError'}); if (!_.isUndefined(errEvent)) { const errCode = errEvent.args.errorId.toNumber(); - const humanReadableErrMessage = this.exchangeContractErrCodesToMsg[errCode]; - throw new Error(humanReadableErrMessage); + const errMessage = this.exchangeContractErrCodesToMsg[errCode]; + throw new Error(errMessage); } } private async getExchangeContractAsync(): Promise { diff --git a/src/types.ts b/src/types.ts index c3a19d3b6..7c5e1825d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -77,6 +77,14 @@ export enum ExchangeContractErrCodes { ERROR_CANCEL_NO_VALUE, // Order has already been fully filled or cancelled } +export const ExchangeContractErrs = strEnum([ + 'ORDER_EXPIRED', + 'ORDER_REMAINING_FILL_AMOUNT_ZERO', + 'ORDER_ROUNDING_ERROR', + 'ORDER_BALANCE_ALLOWANCE_ERROR', +]); +export type ExchangeContractErrs = keyof typeof ExchangeContractErrs; + export const FillOrderValidationErrs = strEnum([ 'FILL_AMOUNT_IS_ZERO', 'NOT_A_TAKER', -- cgit From a1041348d5695ee3b84433e9874176e85543a4e0 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 1 Jun 2017 16:07:43 +0200 Subject: Get getSenderAddressOrThrowAsync everywhere where we throw if the senderAddress doesn't exist --- src/0x.js.ts | 11 ++++------- src/web3_wrapper.ts | 16 ++++++++-------- 2 files changed, 12 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/0x.js.ts b/src/0x.js.ts index 1a46fe9a5..a29c25e0c 100644 --- a/src/0x.js.ts +++ b/src/0x.js.ts @@ -157,6 +157,8 @@ export class ZeroEx { public async signOrderHashAsync(orderHashHex: string): Promise { assert.isHexString('orderHashHex', orderHashHex); + const makerAddress = await this.web3Wrapper.getSenderAddressOrThrowAsync(); + let msgHashHex; const nodeVersion = await this.web3Wrapper.getNodeVersionAsync(); const isParityNode = utils.isParityNode(nodeVersion); @@ -169,12 +171,7 @@ export class ZeroEx { msgHashHex = ethUtil.bufferToHex(msgHashBuff); } - const makerAddressIfExists = await this.web3Wrapper.getSenderAddressIfExistsAsync(); - if (_.isUndefined(makerAddressIfExists)) { - throw new Error(ZeroExError.USER_HAS_NO_ASSOCIATED_ADDRESSES); - } - - const signature = await this.web3Wrapper.signTransactionAsync(makerAddressIfExists, msgHashHex); + const signature = await this.web3Wrapper.signTransactionAsync(makerAddress, msgHashHex); let signatureData; const [nodeVersionNumber] = findVersions(nodeVersion); @@ -204,7 +201,7 @@ export class ZeroEx { r: ethUtil.bufferToHex(r), s: ethUtil.bufferToHex(s), }; - const isValidSignature = ZeroEx.isValidSignature(orderHashHex, ecSignature, makerAddressIfExists); + const isValidSignature = ZeroEx.isValidSignature(orderHashHex, ecSignature, makerAddress); if (!isValidSignature) { throw new Error(ZeroExError.INVALID_SIGNATURE); } diff --git a/src/web3_wrapper.ts b/src/web3_wrapper.ts index 70e77dbe3..c1263222a 100644 --- a/src/web3_wrapper.ts +++ b/src/web3_wrapper.ts @@ -20,14 +20,6 @@ export class Web3Wrapper { public setDefaultAccount(address: string): void { this.web3.eth.defaultAccount = address; } - public async getSenderAddressIfExistsAsync(): Promise { - const defaultAccount = this.web3.eth.defaultAccount; - if (!_.isUndefined(defaultAccount)) { - return defaultAccount; - } - const firstAccount = await this.getFirstAddressIfExistsAsync(); - return firstAccount; - } public async getSenderAddressOrThrowAsync(): Promise { const senderAddressIfExists = await this.getSenderAddressIfExistsAsync(); assert.assert(!_.isUndefined(senderAddressIfExists), ZeroExError.USER_HAS_NO_ASSOCIATED_ADDRESSES); @@ -74,6 +66,14 @@ export class Web3Wrapper { const {timestamp} = await promisify(this.web3.eth.getBlock)(blockHash); return timestamp; } + private async getSenderAddressIfExistsAsync(): Promise { + const defaultAccount = this.web3.eth.defaultAccount; + if (!_.isUndefined(defaultAccount)) { + return defaultAccount; + } + const firstAccount = await this.getFirstAddressIfExistsAsync(); + return firstAccount; + } private async getNetworkAsync(): Promise { const networkId = await promisify(this.web3.version.getNetwork)(); return networkId; -- cgit From 771c88ec791cb6bedf2ddd3418e89dec1581e326 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 1 Jun 2017 16:11:25 +0200 Subject: Revert "Add EXPIRED test" This reverts commit d8e35c364ea94b606810b340fb02d8706e257c3c. --- src/contract_wrappers/exchange_wrapper.ts | 3 --- src/types.ts | 1 - 2 files changed, 4 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index 1232b969b..dbb427d2c 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -120,9 +120,6 @@ export class ExchangeWrapper extends ContractWrapper { if (signedOrder.taker !== constants.NULL_ADDRESS && signedOrder.taker !== senderAddress) { throw new Error(FillOrderValidationErrs.NOT_A_TAKER); } - if (signedOrder.expirationUnixTimestampSec.lessThan(Date.now() / 1000)) { - throw new Error(FillOrderValidationErrs.EXPIRED); - } } private async getExchangeInstanceOrThrowAsync(): Promise { const contractInstance = await this.instantiateContractIfExistsAsync((ExchangeArtifacts as any)); diff --git a/src/types.ts b/src/types.ts index 7c5e1825d..216026b3d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -88,7 +88,6 @@ export type ExchangeContractErrs = keyof typeof ExchangeContractErrs; export const FillOrderValidationErrs = strEnum([ 'FILL_AMOUNT_IS_ZERO', 'NOT_A_TAKER', - 'EXPIRED', ]); export type FillOrderValidationErrs = keyof typeof FillOrderValidationErrs; -- cgit From 7d64ce1220c21c6a4c9f06df39132aceb72c4461 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 1 Jun 2017 16:15:30 +0200 Subject: Add EXPIRED error type --- src/types.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/types.ts b/src/types.ts index 216026b3d..7c5e1825d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -88,6 +88,7 @@ export type ExchangeContractErrs = keyof typeof ExchangeContractErrs; export const FillOrderValidationErrs = strEnum([ 'FILL_AMOUNT_IS_ZERO', 'NOT_A_TAKER', + 'EXPIRED', ]); export type FillOrderValidationErrs = keyof typeof FillOrderValidationErrs; -- cgit From 78259dc2af07a7c56b89669cd0b6a1c7b997092b Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 1 Jun 2017 16:15:58 +0200 Subject: Add expired check --- src/contract_wrappers/exchange_wrapper.ts | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index dbb427d2c..1232b969b 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -120,6 +120,9 @@ export class ExchangeWrapper extends ContractWrapper { if (signedOrder.taker !== constants.NULL_ADDRESS && signedOrder.taker !== senderAddress) { throw new Error(FillOrderValidationErrs.NOT_A_TAKER); } + if (signedOrder.expirationUnixTimestampSec.lessThan(Date.now() / 1000)) { + throw new Error(FillOrderValidationErrs.EXPIRED); + } } private async getExchangeInstanceOrThrowAsync(): Promise { const contractInstance = await this.instantiateContractIfExistsAsync((ExchangeArtifacts as any)); -- cgit From 44f11442424c88d1130ee398d0714636c5ade045 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 1 Jun 2017 16:21:01 +0200 Subject: Add comment for fillOrderAsync method, rename fillAmount to fillTakerAmountInBaseUnits and remove default value for shouldCheckTransfer --- src/contract_wrappers/exchange_wrapper.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index dbb427d2c..40f22bd28 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -57,18 +57,23 @@ export class ExchangeWrapper extends ContractWrapper { ); return isValidSignature; } - public async fillOrderAsync(signedOrder: SignedOrder, fillAmount: BigNumber.BigNumber, - shouldCheckTransfer: boolean = true): Promise { + /** + * Fills a signed order with a specified amount in baseUnits of the taker token. The caller can + * decide whether they want the call to throw if the balance/allowance checks fail by setting + * shouldCheckTransfer to false. If true, the call will fail without throwing, preserving gas costs. + */ + public async fillOrderAsync(signedOrder: SignedOrder, fillTakerAmountInBaseUnits: BigNumber.BigNumber, + shouldCheckTransfer: boolean): Promise { assert.doesConformToSchema('signedOrder', SchemaValidator.convertToJSONSchemaCompatibleObject(signedOrder as object), signedOrderSchema); - assert.isBigNumber('fillAmount', fillAmount); + assert.isBigNumber('fillTakerAmountInBaseUnits', fillTakerAmountInBaseUnits); assert.isBoolean('shouldCheckTransfer', shouldCheckTransfer); const senderAddress = await this.web3Wrapper.getSenderAddressOrThrowAsync(); const exchangeInstance = await this.getExchangeInstanceOrThrowAsync(); - this.validateFillOrder(signedOrder, fillAmount, senderAddress, shouldCheckTransfer); + this.validateFillOrder(signedOrder, fillTakerAmountInBaseUnits, senderAddress, shouldCheckTransfer); const orderAddresses: OrderAddresses = [ signedOrder.maker, @@ -88,7 +93,7 @@ export class ExchangeWrapper extends ContractWrapper { const gas = await exchangeInstance.fill.estimateGas( orderAddresses, orderValues, - fillAmount, + fillTakerAmountInBaseUnits, shouldCheckTransfer, signedOrder.ecSignature.v, signedOrder.ecSignature.r, @@ -100,7 +105,7 @@ export class ExchangeWrapper extends ContractWrapper { const response: ContractResponse = await exchangeInstance.fill( orderAddresses, orderValues, - fillAmount, + fillTakerAmountInBaseUnits, shouldCheckTransfer, signedOrder.ecSignature.v, signedOrder.ecSignature.r, -- cgit From 6c590354c7536ae3ed941fb757be9d0240739e14 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 1 Jun 2017 16:25:28 +0200 Subject: improve comment --- src/contract_wrappers/exchange_wrapper.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index ded0d3519..96bb4c0a0 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -58,9 +58,9 @@ export class ExchangeWrapper extends ContractWrapper { return isValidSignature; } /** - * Fills a signed order with a specified amount in baseUnits of the taker token. The caller can + * Fills a signed order with a fillAmount denominated in baseUnits of the taker token. The caller can * decide whether they want the call to throw if the balance/allowance checks fail by setting - * shouldCheckTransfer to false. If true, the call will fail without throwing, preserving gas costs. + * shouldCheckTransfer to false. If set to true, the call will fail without throwing, preserving gas costs. */ public async fillOrderAsync(signedOrder: SignedOrder, fillTakerAmountInBaseUnits: BigNumber.BigNumber, shouldCheckTransfer: boolean): Promise { -- cgit From f756e1d24e4a27b4e0ce8078884408a321fe2d28 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 1 Jun 2017 16:25:37 +0200 Subject: remove unneeded method --- src/contract_wrappers/exchange_wrapper.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index 96bb4c0a0..39b6d27b4 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -71,7 +71,7 @@ export class ExchangeWrapper extends ContractWrapper { assert.isBoolean('shouldCheckTransfer', shouldCheckTransfer); const senderAddress = await this.web3Wrapper.getSenderAddressOrThrowAsync(); - const exchangeInstance = await this.getExchangeInstanceOrThrowAsync(); + const exchangeInstance = await this.getExchangeContractAsync(); this.validateFillOrder(signedOrder, fillTakerAmountInBaseUnits, senderAddress, shouldCheckTransfer); @@ -129,10 +129,6 @@ export class ExchangeWrapper extends ContractWrapper { throw new Error(FillOrderValidationErrs.EXPIRED); } } - private async getExchangeInstanceOrThrowAsync(): Promise { - const contractInstance = await this.instantiateContractIfExistsAsync((ExchangeArtifacts as any)); - return contractInstance as ExchangeContract; - } private throwErrorLogsAsErrors(logs: ContractEvent[]): void { const errEvent = _.find(logs, {event: 'LogError'}); if (!_.isUndefined(errEvent)) { -- cgit From fe025506c97da7d1d32fae0973624d49470340b9 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 1 Jun 2017 16:30:06 +0200 Subject: remove unused arg --- src/contract_wrappers/exchange_wrapper.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index 39b6d27b4..0712dd34a 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -117,8 +117,7 @@ export class ExchangeWrapper extends ContractWrapper { ); this.throwErrorLogsAsErrors(response.logs); } - private validateFillOrder(signedOrder: SignedOrder, fillAmount: BigNumber.BigNumber, senderAddress: string, - shouldCheckTransfer: boolean = true) { + private validateFillOrder(signedOrder: SignedOrder, fillAmount: BigNumber.BigNumber, senderAddress: string) { if (fillAmount.eq(0)) { throw new Error(FillOrderValidationErrs.FILL_AMOUNT_IS_ZERO); } -- cgit From ea42715b9ade871f54d01741ce45f36bce2a6ca2 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 1 Jun 2017 16:54:20 +0200 Subject: remove superfluous param --- src/contract_wrappers/exchange_wrapper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index 0712dd34a..b2d201516 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -73,7 +73,7 @@ export class ExchangeWrapper extends ContractWrapper { const senderAddress = await this.web3Wrapper.getSenderAddressOrThrowAsync(); const exchangeInstance = await this.getExchangeContractAsync(); - this.validateFillOrder(signedOrder, fillTakerAmountInBaseUnits, senderAddress, shouldCheckTransfer); + this.validateFillOrder(signedOrder, fillTakerAmountInBaseUnits, senderAddress); const orderAddresses: OrderAddresses = [ signedOrder.maker, -- cgit From 8193d0f5b28043cbcb005b58790abf32ffee38e1 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 1 Jun 2017 16:55:34 +0200 Subject: rename txData to txOpts --- src/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/types.ts b/src/types.ts index 7c5e1825d..872422af6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -36,9 +36,9 @@ export interface ExchangeContract { isValidSignature: any; fill: { (orderAddresses: OrderAddresses, orderValues: OrderValues, fillAmount: BigNumber.BigNumber, - shouldCheckTransfer: boolean, v: number, r: string, s: string, txData: TxOpts): ContractResponse; + shouldCheckTransfer: boolean, v: number, r: string, s: string, txOpts: TxOpts): ContractResponse; estimateGas: (orderAddresses: OrderAddresses, orderValues: OrderValues, fillAmount: BigNumber.BigNumber, - shouldCheckTransfer: boolean, v: number, r: string, s: string, txData: TxOpts) => number; + shouldCheckTransfer: boolean, v: number, r: string, s: string, txOpts: TxOpts) => number; }; } -- cgit From 24a745092e0f7a626f5cbcfaef2e56567f0ace1d Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 1 Jun 2017 17:38:09 +0200 Subject: Stop passing exchangeAddress into getOrderHash and instead get it from the artifacts --- src/0x.js.ts | 69 ++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/0x.js.ts b/src/0x.js.ts index a29c25e0c..19e38aafe 100644 --- a/src/0x.js.ts +++ b/src/0x.js.ts @@ -19,6 +19,7 @@ import {TokenWrapper} from './contract_wrappers/token_wrapper'; import {SolidityTypes, ECSignature, ZeroExError} from './types'; import {Order} from './types'; import {orderSchema} from './schemas/order_schemas'; +import * as ExchangeArtifacts from '../artifacts/Exchange.json'; // Customize our BigNumber instances bigNumberConfigs.configure(); @@ -32,34 +33,6 @@ export class ZeroEx { public tokenRegistry: TokenRegistryWrapper; public token: TokenWrapper; private web3Wrapper: Web3Wrapper; - /** - * Computes the orderHash given the order parameters and returns it as a hex encoded string. - */ - public static getOrderHashHex(exchangeContractAddr: string, order: Order): string { - assert.doesConformToSchema('order', - SchemaValidator.convertToJSONSchemaCompatibleObject(order as object), - orderSchema); - - const orderParts = [ - {value: exchangeContractAddr, type: SolidityTypes.address}, - {value: order.maker, type: SolidityTypes.address}, - {value: order.taker, type: SolidityTypes.address}, - {value: order.makerTokenAddress, type: SolidityTypes.address}, - {value: order.takerTokenAddress, type: SolidityTypes.address}, - {value: order.feeRecipient, type: SolidityTypes.address}, - {value: utils.bigNumberToBN(order.makerTokenAmount), type: SolidityTypes.uint256}, - {value: utils.bigNumberToBN(order.takerTokenAmount), type: SolidityTypes.uint256}, - {value: utils.bigNumberToBN(order.makerFee), type: SolidityTypes.uint256}, - {value: utils.bigNumberToBN(order.takerFee), type: SolidityTypes.uint256}, - {value: utils.bigNumberToBN(order.expirationUnixTimestampSec), type: SolidityTypes.uint256}, - {value: utils.bigNumberToBN(order.salt), type: SolidityTypes.uint256}, - ]; - const types = _.map(orderParts, o => o.type); - const values = _.map(orderParts, o => o.value); - const hashBuff = ethABI.soliditySHA3(types, values); - const hashHex = ethUtil.bufferToHex(hashBuff); - return hashHex; - } /** * Verifies that the elliptic curve signature `signature` was generated * by signing `data` with the private key corresponding to the `signerAddressHex` address. @@ -150,6 +123,35 @@ export class ZeroEx { public setDefaultAccount(account: string): void { this.web3Wrapper.setDefaultAccount(account); } + /** + * Computes the orderHash given the order parameters and returns it as a hex encoded string. + */ + public async getOrderHashHexAsync(order: Order): Promise { + const exchangeContractAddr = await this.getExchangeAddressAsync(); + assert.doesConformToSchema('order', + SchemaValidator.convertToJSONSchemaCompatibleObject(order as object), + orderSchema); + + const orderParts = [ + {value: exchangeContractAddr, type: SolidityTypes.address}, + {value: order.maker, type: SolidityTypes.address}, + {value: order.taker, type: SolidityTypes.address}, + {value: order.makerTokenAddress, type: SolidityTypes.address}, + {value: order.takerTokenAddress, type: SolidityTypes.address}, + {value: order.feeRecipient, type: SolidityTypes.address}, + {value: utils.bigNumberToBN(order.makerTokenAmount), type: SolidityTypes.uint256}, + {value: utils.bigNumberToBN(order.takerTokenAmount), type: SolidityTypes.uint256}, + {value: utils.bigNumberToBN(order.makerFee), type: SolidityTypes.uint256}, + {value: utils.bigNumberToBN(order.takerFee), type: SolidityTypes.uint256}, + {value: utils.bigNumberToBN(order.expirationUnixTimestampSec), type: SolidityTypes.uint256}, + {value: utils.bigNumberToBN(order.salt), type: SolidityTypes.uint256}, + ]; + const types = _.map(orderParts, o => o.type); + const values = _.map(orderParts, o => o.value); + const hashBuff = ethABI.soliditySHA3(types, values); + const hashHex = ethUtil.bufferToHex(hashBuff); + return hashHex; + } /** * Signs an orderHash and returns it's elliptic curve signature * This method currently supports TestRPC, Geth and Parity above and below V1.6.6 @@ -207,4 +209,15 @@ export class ZeroEx { } return ecSignature; } + private async getExchangeAddressAsync() { + const networkIdIfExists = await this.web3Wrapper.getNetworkIdIfExistsAsync(); + const exchangeNetworkConfigsIfExists = _.isUndefined(networkIdIfExists) ? + undefined : + (ExchangeArtifacts as any).networks[networkIdIfExists]; + if (_.isUndefined(exchangeNetworkConfigsIfExists)) { + throw new Error(ZeroExError.CONTRACT_NOT_DEPLOYED_ON_NETWORK); + } + const exchangeAddress = exchangeNetworkConfigsIfExists.address; + return exchangeAddress; + } } -- cgit From 29955d3606f836a14bd491a8779f6a607d5fa469 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 1 Jun 2017 17:49:41 +0200 Subject: Fix import --- src/0x.js.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/0x.js.ts b/src/0x.js.ts index 19e38aafe..336700a54 100644 --- a/src/0x.js.ts +++ b/src/0x.js.ts @@ -19,7 +19,7 @@ import {TokenWrapper} from './contract_wrappers/token_wrapper'; import {SolidityTypes, ECSignature, ZeroExError} from './types'; import {Order} from './types'; import {orderSchema} from './schemas/order_schemas'; -import * as ExchangeArtifacts from '../artifacts/Exchange.json'; +import * as ExchangeArtifacts from './artifacts/Exchange.json'; // Customize our BigNumber instances bigNumberConfigs.configure(); -- cgit