Update order utils to use new order schema

This commit is contained in:
Amir Bandeali 2019-04-05 15:04:28 -07:00
parent 2f0ee84b71
commit e30b8999d4
7 changed files with 46 additions and 29 deletions

View File

@ -125,6 +125,8 @@ export const constants = {
{ name: 'salt', type: 'uint256' }, { name: 'salt', type: 'uint256' },
{ name: 'makerAssetData', type: 'bytes' }, { name: 'makerAssetData', type: 'bytes' },
{ name: 'takerAssetData', type: 'bytes' }, { name: 'takerAssetData', type: 'bytes' },
{ name: 'makerFeeAssetData', type: 'bytes' },
{ name: 'takerFeeAssetData', type: 'bytes' },
], ],
}, },
EXCHANGE_ZEROEX_TRANSACTION_SCHEMA: { EXCHANGE_ZEROEX_TRANSACTION_SCHEMA: {

View File

@ -42,6 +42,8 @@ export const orderFactory = {
takerAssetAmount, takerAssetAmount,
makerAssetData, makerAssetData,
takerAssetData, takerAssetData,
makerFeeAssetData: createOrderOpts.makerFeeAssetData || makerAssetData,
takerFeeAssetData: createOrderOpts.takerFeeAssetData || takerAssetData,
takerAddress: createOrderOpts.takerAddress || defaultCreateOrderOpts.takerAddress, takerAddress: createOrderOpts.takerAddress || defaultCreateOrderOpts.takerAddress,
senderAddress: createOrderOpts.senderAddress || defaultCreateOrderOpts.senderAddress, senderAddress: createOrderOpts.senderAddress || defaultCreateOrderOpts.senderAddress,
makerFee: createOrderOpts.makerFee || defaultCreateOrderOpts.makerFee, makerFee: createOrderOpts.makerFee || defaultCreateOrderOpts.makerFee,
@ -110,6 +112,8 @@ function generateEmptyOrder(chainId: number): Order {
takerAssetAmount: constants.ZERO_AMOUNT, takerAssetAmount: constants.ZERO_AMOUNT,
makerAssetData: constants.NULL_BYTES, makerAssetData: constants.NULL_BYTES,
takerAssetData: constants.NULL_BYTES, takerAssetData: constants.NULL_BYTES,
makerFeeAssetData: constants.NULL_BYTES,
takerFeeAssetData: constants.NULL_BYTES,
salt: generatePseudoRandomSalt(), salt: generatePseudoRandomSalt(),
feeRecipientAddress: constants.NULL_ADDRESS, feeRecipientAddress: constants.NULL_ADDRESS,
expirationTimeSeconds: constants.INFINITE_TIMESTAMP_SEC, expirationTimeSeconds: constants.INFINITE_TIMESTAMP_SEC,

View File

@ -1,7 +1,7 @@
import { BigNumber } from '@0x/utils'; import { BigNumber } from '@0x/utils';
export class RemainingFillableCalculator { export class RemainingFillableCalculator {
private readonly _isTraderAssetZRX: boolean; private readonly _isPercentageFee: boolean;
// Transferrable Amount is the minimum of Approval and Balance // Transferrable Amount is the minimum of Approval and Balance
private readonly _transferrableAssetAmount: BigNumber; private readonly _transferrableAssetAmount: BigNumber;
private readonly _transferrableFeeAmount: BigNumber; private readonly _transferrableFeeAmount: BigNumber;
@ -12,14 +12,14 @@ export class RemainingFillableCalculator {
constructor( constructor(
orderFee: BigNumber, orderFee: BigNumber,
orderAssetAmount: BigNumber, orderAssetAmount: BigNumber,
isTraderAssetZRX: boolean, isPercentageFee: boolean,
transferrableAssetAmount: BigNumber, transferrableAssetAmount: BigNumber,
transferrableFeeAmount: BigNumber, transferrableFeeAmount: BigNumber,
remainingOrderAssetAmount: BigNumber, remainingOrderAssetAmount: BigNumber,
) { ) {
this._orderFee = orderFee; this._orderFee = orderFee;
this._orderAssetAmount = orderAssetAmount; this._orderAssetAmount = orderAssetAmount;
this._isTraderAssetZRX = isTraderAssetZRX; this._isPercentageFee = isPercentageFee;
this._transferrableAssetAmount = transferrableAssetAmount; this._transferrableAssetAmount = transferrableAssetAmount;
this._transferrableFeeAmount = transferrableFeeAmount; this._transferrableFeeAmount = transferrableFeeAmount;
this._remainingOrderAssetAmount = remainingOrderAssetAmount; this._remainingOrderAssetAmount = remainingOrderAssetAmount;
@ -37,10 +37,10 @@ export class RemainingFillableCalculator {
return this._calculatePartiallyFillableAssetAmount(); return this._calculatePartiallyFillableAssetAmount();
} }
private _hasSufficientFundsForFeeAndTransferAmount(): boolean { private _hasSufficientFundsForFeeAndTransferAmount(): boolean {
if (this._isTraderAssetZRX) { if (this._isPercentageFee) {
const totalZRXTransferAmountRequired = this._remainingOrderAssetAmount.plus(this._remainingOrderFeeAmount); const totalTransferAmountRequired = this._remainingOrderAssetAmount.plus(this._remainingOrderFeeAmount);
const hasSufficientFunds = this._transferrableAssetAmount.isGreaterThanOrEqualTo( const hasSufficientFunds = this._transferrableAssetAmount.isGreaterThanOrEqualTo(
totalZRXTransferAmountRequired, totalTransferAmountRequired,
); );
return hasSufficientFunds; return hasSufficientFunds;
} else { } else {
@ -64,13 +64,13 @@ export class RemainingFillableCalculator {
// The number of times the trader can fill the order, given the traders asset Balance // The number of times the trader can fill the order, given the traders asset Balance
// Assuming a balance of 150 wei, and an orderToFeeRatio of 100:1, trader can fill this order 1 time. // Assuming a balance of 150 wei, and an orderToFeeRatio of 100:1, trader can fill this order 1 time.
let fillableTimesInAssetUnits = this._transferrableAssetAmount.dividedBy(orderToFeeRatio); let fillableTimesInAssetUnits = this._transferrableAssetAmount.dividedBy(orderToFeeRatio);
if (this._isTraderAssetZRX) { if (this._isPercentageFee) {
// If ZRX is the trader asset, the Fee and the trader fill amount need to be removed from the same pool; // If ZRX is the trader asset, the Fee and the trader fill amount need to be removed from the same pool;
// 200 ZRXwei for 2ZRXwei fee can only be filled once (need 202 ZRXwei) // 200 ZRXwei for 2ZRXwei fee can only be filled once (need 202 ZRXwei)
const totalZRXTokenPooled = this._transferrableAssetAmount; const totalAssetPooled = this._transferrableAssetAmount;
// The purchasing power here is less as the tokens are taken from the same Pool // The purchasing power here is less as the tokens are taken from the same Pool
// For every one number of fills, we have to take an extra ZRX out of the pool // For every one number of fills, we have to take an extra ZRX out of the pool
fillableTimesInAssetUnits = totalZRXTokenPooled.dividedBy(orderToFeeRatio.plus(new BigNumber(1))); fillableTimesInAssetUnits = totalAssetPooled.dividedBy(orderToFeeRatio.plus(new BigNumber(1)));
} }
// When Ratio is not fully divisible there can be remainders which cannot be represented, so they are floored. // When Ratio is not fully divisible there can be remainders which cannot be represented, so they are floored.
// This can result in a RoundingError being thrown by the Exchange Contract. // This can result in a RoundingError being thrown by the Exchange Contract.

View File

@ -23,6 +23,8 @@ export interface CreateOrderOpts {
feeRecipientAddress?: string; feeRecipientAddress?: string;
salt?: BigNumber; salt?: BigNumber;
expirationTimeSeconds?: BigNumber; expirationTimeSeconds?: BigNumber;
makerFeeAssetData?: string;
takerFeeAssetData?: string;
} }
/** /**

View File

@ -14,7 +14,8 @@ const expect = chai.expect;
describe('Order hashing', () => { describe('Order hashing', () => {
describe('#getOrderHashHex', () => { describe('#getOrderHashHex', () => {
const expectedOrderHash = '0x507a818f74a0400444af08a1f58fa99b8df80ace57bfbdb5da304d9d1713e8ba'; // const expectedOrderHash = '0x507a818f74a0400444af08a1f58fa99b8df80ace57bfbdb5da304d9d1713e8ba';
const expectedOrderHash = '0x67f2637ce3098736611e86a1fd6fa25bef559d547c8751813f80e76507f344ab';
const fakeExchangeContractAddress = '0x1dc4c1cefef38a777b15aa20260a54e584b16c48'; const fakeExchangeContractAddress = '0x1dc4c1cefef38a777b15aa20260a54e584b16c48';
const fakeChainID = 1337; const fakeChainID = 1337;
const order: Order = { const order: Order = {
@ -24,6 +25,8 @@ describe('Order hashing', () => {
feeRecipientAddress: constants.NULL_ADDRESS, feeRecipientAddress: constants.NULL_ADDRESS,
makerAssetData: constants.NULL_ADDRESS, makerAssetData: constants.NULL_ADDRESS,
takerAssetData: constants.NULL_ADDRESS, takerAssetData: constants.NULL_ADDRESS,
makerFeeAssetData: constants.NULL_ADDRESS,
takerFeeAssetData: constants.NULL_ADDRESS,
salt: new BigNumber(0), salt: new BigNumber(0),
makerFee: new BigNumber(0), makerFee: new BigNumber(0),
takerFee: new BigNumber(0), takerFee: new BigNumber(0),

View File

@ -20,9 +20,11 @@ describe('RemainingFillableCalculator', () => {
let makerAmount: BigNumber; let makerAmount: BigNumber;
let takerAmount: BigNumber; let takerAmount: BigNumber;
let makerFeeAmount: BigNumber; let makerFeeAmount: BigNumber;
let isMakeAssetZRX: boolean; let isPercentageFee: boolean;
const makerAssetData: string = '0x1'; const makerAssetData: string = '0x1';
const takerAssetData: string = '0x2'; const takerAssetData: string = '0x2';
const makerFeeAssetData: string = '0x03';
const takerFeeAssetData: string = '0x04';
const decimals: number = 4; const decimals: number = 4;
const zero: BigNumber = new BigNumber(0); const zero: BigNumber = new BigNumber(0);
const chainId: number = 1337; const chainId: number = 1337;
@ -53,6 +55,8 @@ describe('RemainingFillableCalculator', () => {
takerAssetAmount: takerAmount, takerAssetAmount: takerAmount,
makerAssetData, makerAssetData,
takerAssetData, takerAssetData,
makerFeeAssetData,
takerFeeAssetData,
salt: zero, salt: zero,
expirationTimeSeconds: zero, expirationTimeSeconds: zero,
domain: { domain: {
@ -61,9 +65,9 @@ describe('RemainingFillableCalculator', () => {
}, },
}; };
} }
describe('Maker token is NOT ZRX', () => { describe('Maker asset is not fee asset', () => {
before(async () => { before(async () => {
isMakeAssetZRX = false; isPercentageFee = false;
}); });
it('calculates the correct amount when unfilled and funds available', () => { it('calculates the correct amount when unfilled and funds available', () => {
signedOrder = buildSignedOrder(); signedOrder = buildSignedOrder();
@ -71,7 +75,7 @@ describe('RemainingFillableCalculator', () => {
calculator = new RemainingFillableCalculator( calculator = new RemainingFillableCalculator(
signedOrder.makerFee, signedOrder.makerFee,
signedOrder.makerAssetAmount, signedOrder.makerAssetAmount,
isMakeAssetZRX, isPercentageFee,
transferrableMakeAssetAmount, transferrableMakeAssetAmount,
transferrableMakerFeeTokenAmount, transferrableMakerFeeTokenAmount,
remainingMakeAssetAmount, remainingMakeAssetAmount,
@ -84,7 +88,7 @@ describe('RemainingFillableCalculator', () => {
calculator = new RemainingFillableCalculator( calculator = new RemainingFillableCalculator(
signedOrder.makerFee, signedOrder.makerFee,
signedOrder.makerAssetAmount, signedOrder.makerAssetAmount,
isMakeAssetZRX, isPercentageFee,
transferrableMakeAssetAmount, transferrableMakeAssetAmount,
transferrableMakerFeeTokenAmount, transferrableMakerFeeTokenAmount,
remainingMakeAssetAmount, remainingMakeAssetAmount,
@ -98,7 +102,7 @@ describe('RemainingFillableCalculator', () => {
calculator = new RemainingFillableCalculator( calculator = new RemainingFillableCalculator(
signedOrder.makerFee, signedOrder.makerFee,
signedOrder.makerAssetAmount, signedOrder.makerAssetAmount,
isMakeAssetZRX, isPercentageFee,
transferrableMakeAssetAmount, transferrableMakeAssetAmount,
transferrableMakerFeeTokenAmount, transferrableMakerFeeTokenAmount,
remainingMakeAssetAmount, remainingMakeAssetAmount,
@ -113,7 +117,7 @@ describe('RemainingFillableCalculator', () => {
calculator = new RemainingFillableCalculator( calculator = new RemainingFillableCalculator(
signedOrder.makerFee, signedOrder.makerFee,
signedOrder.makerAssetAmount, signedOrder.makerAssetAmount,
isMakeAssetZRX, isPercentageFee,
transferrableMakeAssetAmount, transferrableMakeAssetAmount,
transferrableMakerFeeTokenAmount, transferrableMakerFeeTokenAmount,
remainingMakeAssetAmount, remainingMakeAssetAmount,
@ -136,7 +140,7 @@ describe('RemainingFillableCalculator', () => {
calculator = new RemainingFillableCalculator( calculator = new RemainingFillableCalculator(
signedOrder.makerFee, signedOrder.makerFee,
signedOrder.makerAssetAmount, signedOrder.makerAssetAmount,
isMakeAssetZRX, isPercentageFee,
transferrableMakeAssetAmount, transferrableMakeAssetAmount,
transferrableMakerFeeTokenAmount, transferrableMakerFeeTokenAmount,
remainingMakeAssetAmount, remainingMakeAssetAmount,
@ -144,7 +148,7 @@ describe('RemainingFillableCalculator', () => {
expect(calculator.computeRemainingFillable()).to.be.bignumber.equal(transferrableMakeAssetAmount); expect(calculator.computeRemainingFillable()).to.be.bignumber.equal(transferrableMakeAssetAmount);
}); });
}); });
describe('Ratio is not evenly divisble', () => { describe('Ratio is not evenly divisible', () => {
beforeEach(async () => { beforeEach(async () => {
[makerAmount, takerAmount, makerFeeAmount] = [ [makerAmount, takerAmount, makerFeeAmount] = [
Web3Wrapper.toBaseUnitAmount(new BigNumber(3), decimals), Web3Wrapper.toBaseUnitAmount(new BigNumber(3), decimals),
@ -160,7 +164,7 @@ describe('RemainingFillableCalculator', () => {
calculator = new RemainingFillableCalculator( calculator = new RemainingFillableCalculator(
signedOrder.makerFee, signedOrder.makerFee,
signedOrder.makerAssetAmount, signedOrder.makerAssetAmount,
isMakeAssetZRX, isPercentageFee,
transferrableMakeAssetAmount, transferrableMakeAssetAmount,
transferrableMakerFeeTokenAmount, transferrableMakerFeeTokenAmount,
remainingMakeAssetAmount, remainingMakeAssetAmount,
@ -174,9 +178,9 @@ describe('RemainingFillableCalculator', () => {
}); });
}); });
}); });
describe('Maker Token is ZRX', () => { describe('Maker asset is fee asset', () => {
before(async () => { before(async () => {
isMakeAssetZRX = true; isPercentageFee = true;
}); });
it('calculates the correct amount when unfilled and funds available', () => { it('calculates the correct amount when unfilled and funds available', () => {
signedOrder = buildSignedOrder(); signedOrder = buildSignedOrder();
@ -186,7 +190,7 @@ describe('RemainingFillableCalculator', () => {
calculator = new RemainingFillableCalculator( calculator = new RemainingFillableCalculator(
signedOrder.makerFee, signedOrder.makerFee,
signedOrder.makerAssetAmount, signedOrder.makerAssetAmount,
isMakeAssetZRX, isPercentageFee,
transferrableMakeAssetAmount, transferrableMakeAssetAmount,
transferrableMakerFeeTokenAmount, transferrableMakerFeeTokenAmount,
remainingMakeAssetAmount, remainingMakeAssetAmount,
@ -199,7 +203,7 @@ describe('RemainingFillableCalculator', () => {
calculator = new RemainingFillableCalculator( calculator = new RemainingFillableCalculator(
signedOrder.makerFee, signedOrder.makerFee,
signedOrder.makerAssetAmount, signedOrder.makerAssetAmount,
isMakeAssetZRX, isPercentageFee,
transferrableMakeAssetAmount, transferrableMakeAssetAmount,
transferrableMakerFeeTokenAmount, transferrableMakerFeeTokenAmount,
remainingMakeAssetAmount, remainingMakeAssetAmount,
@ -214,7 +218,7 @@ describe('RemainingFillableCalculator', () => {
calculator = new RemainingFillableCalculator( calculator = new RemainingFillableCalculator(
signedOrder.makerFee, signedOrder.makerFee,
signedOrder.makerAssetAmount, signedOrder.makerAssetAmount,
isMakeAssetZRX, isPercentageFee,
transferrableMakeAssetAmount, transferrableMakeAssetAmount,
transferrableMakerFeeTokenAmount, transferrableMakerFeeTokenAmount,
remainingMakeAssetAmount, remainingMakeAssetAmount,
@ -233,7 +237,7 @@ describe('RemainingFillableCalculator', () => {
calculator = new RemainingFillableCalculator( calculator = new RemainingFillableCalculator(
signedOrder.makerFee, signedOrder.makerFee,
signedOrder.makerAssetAmount, signedOrder.makerAssetAmount,
isMakeAssetZRX, isPercentageFee,
transferrableMakeAssetAmount, transferrableMakeAssetAmount,
transferrableMakerFeeTokenAmount, transferrableMakerFeeTokenAmount,
remainingMakeAssetAmount, remainingMakeAssetAmount,

View File

@ -33,6 +33,8 @@ describe('Signature utils', () => {
feeRecipientAddress: constants.NULL_ADDRESS, feeRecipientAddress: constants.NULL_ADDRESS,
makerAssetData: constants.NULL_ADDRESS, makerAssetData: constants.NULL_ADDRESS,
takerAssetData: constants.NULL_ADDRESS, takerAssetData: constants.NULL_ADDRESS,
makerFeeAssetData: constants.NULL_ADDRESS,
takerFeeAssetData: constants.NULL_ADDRESS,
salt: new BigNumber(0), salt: new BigNumber(0),
makerFee: new BigNumber(0), makerFee: new BigNumber(0),
takerFee: new BigNumber(0), takerFee: new BigNumber(0),
@ -164,7 +166,7 @@ describe('Signature utils', () => {
describe('#ecSignOrderAsync', () => { describe('#ecSignOrderAsync', () => {
it('should default to eth_sign if eth_signTypedData is unavailable', async () => { it('should default to eth_sign if eth_signTypedData is unavailable', async () => {
const expectedSignature = const expectedSignature =
'0x1c8bb89df0d0b537eced265159e75082086fa6f2c1422e743b36a095711edabf890531b8c37f0060bbd7d282a1a8a98b1497c85ac85a2eefc05854f090831fd9be03'; '0x1c5e6c2a66037230b86a410b1d68108683ee8288d3668af91cab72dde1e1541ca86a50b638ccc743f6194a21dd313e71b4b155b2ad882f874d5d790d37d4623ca203';
const fakeProvider = { const fakeProvider = {
async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback): Promise<void> { async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback): Promise<void> {
@ -358,9 +360,9 @@ describe('Signature utils', () => {
expect(signatureHex).to.eq(signedOrder.signature); expect(signatureHex).to.eq(signedOrder.signature);
expect(isValidSignature).to.eq(true); expect(isValidSignature).to.eq(true);
}); });
it('should return the correct Signature for signatureHex concatenated as R + S + V', async () => { it('should return the correct signature for signatureHex concatenated as R + S + V', async () => {
const expectedSignature = const expectedSignature =
'0x1cdf371e6e60c9f2a0a3a1adcc1b27411e1d88bdb9c7dbae8c6faa38d37c5e330e2b467e08bbde8285d627cc5fc680746b9f97ec9d5e5be3b9fdf7abe37ed3279502'; '0x1c686a55fa3f563115c0f2bc2b1c51964d0b6a05dd5ee862b702275600b7f634970f2275dccc1073f87a916dfde88574385b2d7a3eed0c2bdc08c76bad748d7d9002';
const fakeProvider = { const fakeProvider = {
async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback): Promise<void> { async sendAsync(payload: JSONRPCRequestPayload, callback: JSONRPCErrorCallback): Promise<void> {
if (payload.method === 'eth_signTypedData') { if (payload.method === 'eth_signTypedData') {