Skip to content
This repository has been archived by the owner on Jul 9, 2021. It is now read-only.

Commit

Permalink
Copy dutch auction asset data utils to @0x/order-utils (#1943)
Browse files Browse the repository at this point in the history
* copy dutch auction assetdata utils to @0x/order-utils

* encode/decode dutch auction asset data using order-utils
  • Loading branch information
xianny authored Jul 13, 2019
1 parent eabf6a4 commit 88ae831
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 55 deletions.
2 changes: 1 addition & 1 deletion packages/0x.js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ export {
OrderAndTraderInfo,
TraderInfo,
ValidateOrderFillableOpts,
DutchAuctionData,
} from '@0x/contract-wrappers';

export {
Expand Down Expand Up @@ -85,6 +84,7 @@ export {
ExchangeContractErrs,
Order,
SignedOrder,
DutchAuctionData,
ECSignature,
OrderStateValid,
OrderStateInvalid,
Expand Down
8 changes: 8 additions & 0 deletions packages/contract-wrappers/CHANGELOG.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
[
{
"version": "9.1.5",
"changes": [
{
"note": "Use assetDataUtils for encoding and decoding DutchAuctionData"
}
]
},
{
"timestamp": 1558712885,
"version": "9.1.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@ import { DutchAuctionContract } from '@0x/abi-gen-wrappers';
import { DutchAuction } from '@0x/contract-artifacts';
import { schemas } from '@0x/json-schemas';
import { assetDataUtils } from '@0x/order-utils';
import { DutchAuctionDetails, SignedOrder } from '@0x/types';
import { DutchAuctionData, DutchAuctionDetails, SignedOrder } from '@0x/types';
import { BigNumber } from '@0x/utils';
import { Web3Wrapper } from '@0x/web3-wrapper';
import { ContractAbi } from 'ethereum-types';
import * as ethAbi from 'ethereumjs-abi';
import * as ethUtil from 'ethereumjs-util';
import * as _ from 'lodash';

import { orderTxOptsSchema } from '../schemas/order_tx_opts_schema';
import { txOptsSchema } from '../schemas/tx_opts_schema';
import { DutchAuctionData, DutchAuctionWrapperError, OrderTransactionOpts } from '../types';
import { DutchAuctionWrapperError, OrderTransactionOpts } from '../types';
import { assert } from '../utils/assert';
import { _getDefaultContractAddresses } from '../utils/contract_addresses';

Expand All @@ -36,14 +34,7 @@ export class DutchAuctionWrapper extends ContractWrapper {
beginTimeSeconds: BigNumber,
beginAmount: BigNumber,
): string {
const assetDataBuffer = ethUtil.toBuffer(assetData);
const abiEncodedAuctionData = (ethAbi as any).rawEncode(
['uint256', 'uint256'],
[beginTimeSeconds.toString(), beginAmount.toString()],
);
const abiEncodedAuctionDataBuffer = ethUtil.toBuffer(abiEncodedAuctionData);
const dutchAuctionDataBuffer = Buffer.concat([assetDataBuffer, abiEncodedAuctionDataBuffer]);
const dutchAuctionData = ethUtil.bufferToHex(dutchAuctionDataBuffer);
const dutchAuctionData = assetDataUtils.encodeDutchAuctionAssetData(assetData, beginTimeSeconds, beginAmount);
return dutchAuctionData;
}
/**
Expand All @@ -54,30 +45,8 @@ export class DutchAuctionWrapper extends ContractWrapper {
* @return An object containing the auction asset, auction begin time and auction begin amount.
*/
public static decodeDutchAuctionData(dutchAuctionData: string): DutchAuctionData {
const dutchAuctionDataBuffer = ethUtil.toBuffer(dutchAuctionData);
// Decode asset data
const dutchAuctionDataLengthInBytes = 64;
const assetDataBuffer = dutchAuctionDataBuffer.slice(
0,
dutchAuctionDataBuffer.byteLength - dutchAuctionDataLengthInBytes,
);
const assetDataHex = ethUtil.bufferToHex(assetDataBuffer);
const assetData = assetDataUtils.decodeAssetDataOrThrow(assetDataHex);
// Decode auction details
const dutchAuctionDetailsBuffer = dutchAuctionDataBuffer.slice(
dutchAuctionDataBuffer.byteLength - dutchAuctionDataLengthInBytes,
);
const [beginTimeSecondsAsBN, beginAmountAsBN] = ethAbi.rawDecode(
['uint256', 'uint256'],
dutchAuctionDetailsBuffer,
);
const beginTimeSeconds = new BigNumber(beginTimeSecondsAsBN.toString());
const beginAmount = new BigNumber(beginAmountAsBN.toString());
return {
assetData,
beginTimeSeconds,
beginAmount,
};
const decoded = assetDataUtils.decodeDutchAuctionData(dutchAuctionData);
return decoded;
}
/**
* Instantiate DutchAuctionWrapper
Expand Down
2 changes: 1 addition & 1 deletion packages/contract-wrappers/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ export {
OrderAndTraderInfo,
TraderInfo,
ValidateOrderFillableOpts,
DutchAuctionData,
CoordinatorServerCancellationResponse,
CoordinatorServerError,
} from './types';
Expand All @@ -73,6 +72,7 @@ export {
StaticCallAssetData,
MultiAssetDataWithRecursiveDecoding,
DutchAuctionDetails,
DutchAuctionData,
Order,
SignedOrder,
AssetProxyId,
Expand Down
8 changes: 1 addition & 7 deletions packages/contract-wrappers/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
WETH9Events,
} from '@0x/abi-gen-wrappers';
import { ContractAddresses } from '@0x/contract-addresses';
import { AssetData, OrderState, SignedOrder } from '@0x/types';
import { OrderState, SignedOrder } from '@0x/types';
import { BigNumber } from '@0x/utils';

import { BlockParam, ContractEventArg, DecodedLogArgs, LogEntryEvent, LogWithDecodedArgs } from 'ethereum-types';
Expand Down Expand Up @@ -220,12 +220,6 @@ export enum DutchAuctionWrapperError {
AssetDataMismatch = 'ASSET_DATA_MISMATCH',
}

export interface DutchAuctionData {
assetData: AssetData;
beginTimeSeconds: BigNumber;
beginAmount: BigNumber;
}

export { CoordinatorServerCancellationResponse, CoordinatorServerError } from './utils/coordinator_server_types';

export interface CoordinatorTransaction {
Expand Down
19 changes: 9 additions & 10 deletions packages/order-utils/CHANGELOG.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
[
{
"version": "8.3.0",
"changes": [
{
"note": "Add support for marketSell utils",
"pr": 1914
}
]
},
{
"version": "8.2.0",
"changes": [
{
"note": "Add support for encoding/decoding StaticCallProxy assetData",
"pr": 1863
},
{
"note": "Add support for marketSell utils",
"pr": 1914
},
{
"note": "Add support for encoding/decoding DutchAuction assetData",
"pr": 1943
},
{
"note": "Added `validateMakerTransferThrowIfInvalidAsync` to OrderValidationUtils",
"pr": "1937"
"pr": 1937
}
]
},
Expand Down
56 changes: 56 additions & 0 deletions packages/order-utils/src/asset_data_utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
AssetProxyId,
DutchAuctionData,
ERC1155AssetData,
ERC1155AssetDataNoProxyId,
ERC20AssetData,
Expand All @@ -10,6 +11,8 @@ import {
StaticCallAssetData,
} from '@0x/types';
import { AbiEncoder, BigNumber } from '@0x/utils';
import * as ethAbi from 'ethereumjs-abi';
import * as ethUtil from 'ethereumjs-util';
import * as _ from 'lodash';

import { constants } from './constants';
Expand Down Expand Up @@ -230,6 +233,59 @@ export const assetDataUtils = {
staticCallData: decodedAssetData.staticCallData,
};
},
/**
* Dutch auction details are encoded with the asset data for a 0x order. This function produces a hex
* encoded assetData string, containing information both about the asset being traded and the
* dutch auction; which is usable in the makerAssetData or takerAssetData fields in a 0x order.
* @param assetData Hex encoded assetData string for the asset being auctioned.
* @param beginTimeSeconds Begin time of the dutch auction.
* @param beginAmount Starting amount being sold in the dutch auction.
* @return The hex encoded assetData string.
*/
encodeDutchAuctionAssetData(assetData: string, beginTimeSeconds: BigNumber, beginAmount: BigNumber): string {
const assetDataBuffer = ethUtil.toBuffer(assetData);
const abiEncodedAuctionData = (ethAbi as any).rawEncode(
['uint256', 'uint256'],
[beginTimeSeconds.toString(), beginAmount.toString()],
);
const abiEncodedAuctionDataBuffer = ethUtil.toBuffer(abiEncodedAuctionData);
const dutchAuctionDataBuffer = Buffer.concat([assetDataBuffer, abiEncodedAuctionDataBuffer]);
const dutchAuctionData = ethUtil.bufferToHex(dutchAuctionDataBuffer);
return dutchAuctionData;
},
/**
* Dutch auction details are encoded with the asset data for a 0x order. This function decodes a hex
* encoded assetData string, containing information both about the asset being traded and the
* dutch auction.
* @param dutchAuctionData Hex encoded assetData string for the asset being auctioned.
* @return An object containing the auction asset, auction begin time and auction begin amount.
*/
decodeDutchAuctionData(dutchAuctionData: string): DutchAuctionData {
const dutchAuctionDataBuffer = ethUtil.toBuffer(dutchAuctionData);
// Decode asset data
const dutchAuctionDataLengthInBytes = 64;
const assetDataBuffer = dutchAuctionDataBuffer.slice(
0,
dutchAuctionDataBuffer.byteLength - dutchAuctionDataLengthInBytes,
);
const assetDataHex = ethUtil.bufferToHex(assetDataBuffer);
const assetData = assetDataUtils.decodeAssetDataOrThrow(assetDataHex);
// Decode auction details
const dutchAuctionDetailsBuffer = dutchAuctionDataBuffer.slice(
dutchAuctionDataBuffer.byteLength - dutchAuctionDataLengthInBytes,
);
const [beginTimeSecondsAsBN, beginAmountAsBN] = ethAbi.rawDecode(
['uint256', 'uint256'],
dutchAuctionDetailsBuffer,
);
const beginTimeSeconds = new BigNumber(beginTimeSecondsAsBN.toString());
const beginAmount = new BigNumber(beginAmountAsBN.toString());
return {
assetData,
beginTimeSeconds,
beginAmount,
};
},
/**
* Decode and return the assetProxyId from the assetData
* @param assetData Hex encoded assetData string to decode
Expand Down
2 changes: 2 additions & 0 deletions packages/order-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ export {
OrderRelevantState,
OrderState,
ECSignature,
AssetData,
SingleAssetData,
DutchAuctionData,
ERC20AssetData,
ERC721AssetData,
ERC1155AssetData,
Expand Down
33 changes: 33 additions & 0 deletions packages/order-utils/test/asset_data_utils_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ const KNOWN_MULTI_ASSET_ENCODING = {
'0x94cfcdd7000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000024f47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000204a7cb5fb70000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000003e90000000000000000000000000000000000000000000000000000000000002711000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000007d10000000000000000000000000000000000000000000000000000000000004e210000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c4800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
};

const KNOWN_DUTCH_AUCTION_ENCODING = {
tokenAddress: '0x34d402f14d58e001d8efbe6585051bf9706aa064',
assetData: '0xf47261b000000000000000000000000034d402f14d58e001d8efbe6585051bf9706aa064', // ERC20
beginTimeSeconds: new BigNumber(1562807905),
beginAmount: new BigNumber(5),
dutchAuctionAssetData:
'0xf47261b000000000000000000000000034d402f14d58e001d8efbe6585051bf9706aa064000000000000000000000000000000000000000000000000000000005d268e610000000000000000000000000000000000000000000000000000000000000005',
};

describe('assetDataUtils', () => {
it('should encode ERC20', () => {
const assetData = assetDataUtils.encodeERC20AssetData(KNOWN_ERC20_ENCODING.address);
Expand Down Expand Up @@ -175,4 +184,28 @@ describe('assetDataUtils', () => {
expect(decodedErc1155AssetData2.tokenIds).to.be.deep.equal(KNOWN_ERC1155_ENCODING.tokenIds);
expect(decodedErc1155AssetData2.callbackData).to.be.equal(KNOWN_ERC1155_ENCODING.callbackData);
});
it('should encode Dutch Auction', async () => {
const encodedAssetData = assetDataUtils.encodeDutchAuctionAssetData(
KNOWN_DUTCH_AUCTION_ENCODING.assetData,
KNOWN_DUTCH_AUCTION_ENCODING.beginTimeSeconds,
KNOWN_DUTCH_AUCTION_ENCODING.beginAmount,
);
expect(encodedAssetData).to.be.equal(KNOWN_DUTCH_AUCTION_ENCODING.dutchAuctionAssetData);
});
it('should decode Dutch Auction', async () => {
const { assetData, beginTimeSeconds, beginAmount } = assetDataUtils.decodeDutchAuctionData(
KNOWN_DUTCH_AUCTION_ENCODING.dutchAuctionAssetData,
);

const { assetProxyId, tokenAddress } = assetDataUtils.decodeERC20AssetData(
KNOWN_DUTCH_AUCTION_ENCODING.assetData,
);

// tslint:disable:no-unnecessary-type-assertion
expect((assetData as ERC20AssetData).assetProxyId).to.be.equal(assetProxyId);
expect((assetData as ERC20AssetData).tokenAddress).to.be.equal(tokenAddress);
// tslint:enable:no-unnecessary-type-assertion
expect(beginTimeSeconds).to.deep.equal(KNOWN_DUTCH_AUCTION_ENCODING.beginTimeSeconds);
expect(beginAmount).to.deep.equal(KNOWN_DUTCH_AUCTION_ENCODING.beginAmount);
});
});
6 changes: 6 additions & 0 deletions packages/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,12 @@ export interface MultiAssetDataWithRecursiveDecoding {
nestedAssetData: SingleAssetData[];
}

export interface DutchAuctionData {
assetData: AssetData;
beginTimeSeconds: BigNumber;
beginAmount: BigNumber;
}

export type AssetData = SingleAssetData | MultiAssetData | MultiAssetDataWithRecursiveDecoding;

// TODO: DRY. These should be extracted from contract code.
Expand Down

0 comments on commit 88ae831

Please sign in to comment.