aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contracts/src/utils
diff options
context:
space:
mode:
authorGreg Hysen <hysz@users.noreply.github.com>2018-05-22 05:29:56 +0800
committerGitHub <noreply@github.com>2018-05-22 05:29:56 +0800
commitd460c0e8b9c6f4081803fff4e2d2347be8cd5ce3 (patch)
tree596681d82624683e76cdd507e31c46ffad4df73b /packages/contracts/src/utils
parent0fdf32cf6f0f1def41a1733687e977feb3a652f5 (diff)
parent11b6d290da18ea4690424a2a518413fb39a4a885 (diff)
downloaddexon-sol-tools-d460c0e8b9c6f4081803fff4e2d2347be8cd5ce3.tar
dexon-sol-tools-d460c0e8b9c6f4081803fff4e2d2347be8cd5ce3.tar.gz
dexon-sol-tools-d460c0e8b9c6f4081803fff4e2d2347be8cd5ce3.tar.bz2
dexon-sol-tools-d460c0e8b9c6f4081803fff4e2d2347be8cd5ce3.tar.lz
dexon-sol-tools-d460c0e8b9c6f4081803fff4e2d2347be8cd5ce3.tar.xz
dexon-sol-tools-d460c0e8b9c6f4081803fff4e2d2347be8cd5ce3.tar.zst
dexon-sol-tools-d460c0e8b9c6f4081803fff4e2d2347be8cd5ce3.zip
Merge pull request #572 from 0xProject/feature/contracts/atomicMatching
Atomic Order Matching
Diffstat (limited to 'packages/contracts/src/utils')
-rw-r--r--packages/contracts/src/utils/asset_proxy_utils.ts107
-rw-r--r--packages/contracts/src/utils/exchange_wrapper.ts22
-rw-r--r--packages/contracts/src/utils/order_utils.ts9
-rw-r--r--packages/contracts/src/utils/types.ts66
4 files changed, 196 insertions, 8 deletions
diff --git a/packages/contracts/src/utils/asset_proxy_utils.ts b/packages/contracts/src/utils/asset_proxy_utils.ts
index dc31c3497..c042da5d0 100644
--- a/packages/contracts/src/utils/asset_proxy_utils.ts
+++ b/packages/contracts/src/utils/asset_proxy_utils.ts
@@ -2,12 +2,15 @@ import { BigNumber } from '@0xproject/utils';
import BN = require('bn.js');
import ethUtil = require('ethereumjs-util');
-import { AssetProxyId } from './types';
+import { AssetProxyId, ERC20ProxyData, ERC721ProxyData, ProxyData } from './types';
export const assetProxyUtils = {
encodeAssetProxyId(assetProxyId: AssetProxyId): Buffer {
return ethUtil.toBuffer(assetProxyId);
},
+ decodeAssetProxyId(encodedAssetProxyId: Buffer): AssetProxyId {
+ return ethUtil.bufferToInt(encodedAssetProxyId);
+ },
encodeAddress(address: string): Buffer {
if (!ethUtil.isValidAddress(address)) {
throw new Error(`Invalid Address: ${address}`);
@@ -15,12 +18,24 @@ export const assetProxyUtils = {
const encodedAddress = ethUtil.toBuffer(address);
return encodedAddress;
},
+ decodeAddress(encodedAddress: Buffer): string {
+ const address = ethUtil.bufferToHex(encodedAddress);
+ if (!ethUtil.isValidAddress(address)) {
+ throw new Error(`Invalid Address: ${address}`);
+ }
+ return address;
+ },
encodeUint256(value: BigNumber): Buffer {
const formattedValue = new BN(value.toString(10));
const encodedValue = ethUtil.toBuffer(formattedValue);
const paddedValue = ethUtil.setLengthLeft(encodedValue, 32);
return paddedValue;
},
+ decodeUint256(encodedValue: Buffer): BigNumber {
+ const formattedValue = ethUtil.bufferToHex(encodedValue);
+ const value = new BigNumber(formattedValue, 16);
+ return value;
+ },
encodeERC20ProxyData(tokenAddress: string): string {
const encodedAssetProxyId = assetProxyUtils.encodeAssetProxyId(AssetProxyId.ERC20);
const encodedAddress = assetProxyUtils.encodeAddress(tokenAddress);
@@ -28,6 +43,32 @@ export const assetProxyUtils = {
const encodedMetadataHex = ethUtil.bufferToHex(encodedMetadata);
return encodedMetadataHex;
},
+ decodeERC20ProxyData(proxyData: string): ERC20ProxyData {
+ const encodedProxyMetadata = ethUtil.toBuffer(proxyData);
+ if (encodedProxyMetadata.byteLength !== 21) {
+ throw new Error(
+ `Could not decode ERC20 Proxy Data. Expected length of encoded data to be 21. Got ${
+ encodedProxyMetadata.byteLength
+ }`,
+ );
+ }
+ const encodedAssetProxyId = encodedProxyMetadata.slice(0, 1);
+ const assetProxyId = assetProxyUtils.decodeAssetProxyId(encodedAssetProxyId);
+ if (assetProxyId !== AssetProxyId.ERC20) {
+ throw new Error(
+ `Could not decode ERC20 Proxy Data. Expected Asset Proxy Id to be ERC20 (${
+ AssetProxyId.ERC20
+ }), but got ${assetProxyId}`,
+ );
+ }
+ const encodedTokenAddress = encodedProxyMetadata.slice(1, 21);
+ const tokenAddress = assetProxyUtils.decodeAddress(encodedTokenAddress);
+ const erc20ProxyData = {
+ assetProxyId,
+ tokenAddress,
+ };
+ return erc20ProxyData;
+ },
encodeERC721ProxyData(tokenAddress: string, tokenId: BigNumber): string {
const encodedAssetProxyId = assetProxyUtils.encodeAssetProxyId(AssetProxyId.ERC721);
const encodedAddress = assetProxyUtils.encodeAddress(tokenAddress);
@@ -36,4 +77,68 @@ export const assetProxyUtils = {
const encodedMetadataHex = ethUtil.bufferToHex(encodedMetadata);
return encodedMetadataHex;
},
+ decodeERC721ProxyData(proxyData: string): ERC721ProxyData {
+ const encodedProxyMetadata = ethUtil.toBuffer(proxyData);
+ if (encodedProxyMetadata.byteLength !== 53) {
+ throw new Error(
+ `Could not decode ERC20 Proxy Data. Expected length of encoded data to be 53. Got ${
+ encodedProxyMetadata.byteLength
+ }`,
+ );
+ }
+ const encodedAssetProxyId = encodedProxyMetadata.slice(0, 1);
+ const assetProxyId = assetProxyUtils.decodeAssetProxyId(encodedAssetProxyId);
+ if (assetProxyId !== AssetProxyId.ERC721) {
+ throw new Error(
+ `Could not decode ERC721 Proxy Data. Expected Asset Proxy Id to be ERC721 (${
+ AssetProxyId.ERC721
+ }), but got ${assetProxyId}`,
+ );
+ }
+ const encodedTokenAddress = encodedProxyMetadata.slice(1, 21);
+ const tokenAddress = assetProxyUtils.decodeAddress(encodedTokenAddress);
+ const encodedTokenId = encodedProxyMetadata.slice(21, 53);
+ const tokenId = assetProxyUtils.decodeUint256(encodedTokenId);
+ const erc721ProxyData = {
+ assetProxyId,
+ tokenAddress,
+ tokenId,
+ };
+ return erc721ProxyData;
+ },
+ decodeProxyDataId(proxyData: string): AssetProxyId {
+ const encodedProxyMetadata = ethUtil.toBuffer(proxyData);
+ if (encodedProxyMetadata.byteLength < 1) {
+ throw new Error(
+ `Could not decode Proxy Data. Expected length of encoded data to be at least 1. Got ${
+ encodedProxyMetadata.byteLength
+ }`,
+ );
+ }
+ const encodedAssetProxyId = encodedProxyMetadata.slice(0, 1);
+ const assetProxyId = assetProxyUtils.decodeAssetProxyId(encodedAssetProxyId);
+ return assetProxyId;
+ },
+ decodeProxyData(proxyData: string): ProxyData {
+ const assetProxyId = assetProxyUtils.decodeProxyDataId(proxyData);
+ switch (assetProxyId) {
+ case AssetProxyId.ERC20:
+ const erc20ProxyData = assetProxyUtils.decodeERC20ProxyData(proxyData);
+ const generalizedERC20ProxyData = {
+ assetProxyId,
+ tokenAddress: erc20ProxyData.tokenAddress,
+ };
+ return generalizedERC20ProxyData;
+ case AssetProxyId.ERC721:
+ const erc721ProxyData = assetProxyUtils.decodeERC721ProxyData(proxyData);
+ const generaliedERC721ProxyData = {
+ assetProxyId,
+ tokenAddress: erc721ProxyData.tokenAddress,
+ data: erc721ProxyData.tokenId,
+ };
+ return generaliedERC721ProxyData;
+ default:
+ throw new Error(`Unrecognized asset proxy id: ${assetProxyId}`);
+ }
+ },
};
diff --git a/packages/contracts/src/utils/exchange_wrapper.ts b/packages/contracts/src/utils/exchange_wrapper.ts
index 27fdd698f..46531fa3f 100644
--- a/packages/contracts/src/utils/exchange_wrapper.ts
+++ b/packages/contracts/src/utils/exchange_wrapper.ts
@@ -9,7 +9,7 @@ import { constants } from './constants';
import { formatters } from './formatters';
import { LogDecoder } from './log_decoder';
import { orderUtils } from './order_utils';
-import { AssetProxyId, SignedOrder, SignedTransaction } from './types';
+import { AssetProxyId, OrderInfo, SignedOrder, SignedTransaction } from './types';
export class ExchangeWrapper {
private _exchange: ExchangeContract;
@@ -225,6 +225,26 @@ export class ExchangeWrapper {
const filledAmount = new BigNumber(await this._exchange.filled.callAsync(orderHashHex));
return filledAmount;
}
+ public async getOrderInfoAsync(signedOrder: SignedOrder): Promise<OrderInfo> {
+ const orderInfo = (await this._exchange.getOrderInfo.callAsync(signedOrder)) as OrderInfo;
+ return orderInfo;
+ }
+ public async matchOrdersAsync(
+ signedOrderLeft: SignedOrder,
+ signedOrderRight: SignedOrder,
+ from: string,
+ ): Promise<TransactionReceiptWithDecodedLogs> {
+ const params = orderUtils.createMatchOrders(signedOrderLeft, signedOrderRight);
+ const txHash = await this._exchange.matchOrders.sendTransactionAsync(
+ params.left,
+ params.right,
+ params.leftSignature,
+ params.rightSignature,
+ { from },
+ );
+ const tx = await this._getTxWithDecodedExchangeLogsAsync(txHash);
+ return tx;
+ }
private async _getTxWithDecodedExchangeLogsAsync(txHash: string) {
const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash);
tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address);
diff --git a/packages/contracts/src/utils/order_utils.ts b/packages/contracts/src/utils/order_utils.ts
index 10bbf4f7c..7a482ad9e 100644
--- a/packages/contracts/src/utils/order_utils.ts
+++ b/packages/contracts/src/utils/order_utils.ts
@@ -80,4 +80,13 @@ export const orderUtils = {
const orderHashHex = `0x${orderHashBuff.toString('hex')}`;
return orderHashHex;
},
+ createMatchOrders(signedOrderLeft: SignedOrder, signedOrderRight: SignedOrder) {
+ const fill = {
+ left: orderUtils.getOrderStruct(signedOrderLeft),
+ right: orderUtils.getOrderStruct(signedOrderRight),
+ leftSignature: signedOrderLeft.signature,
+ rightSignature: signedOrderRight.signature,
+ };
+ return fill;
+ },
};
diff --git a/packages/contracts/src/utils/types.ts b/packages/contracts/src/utils/types.ts
index 234b14ef9..8d81adece 100644
--- a/packages/contracts/src/utils/types.ts
+++ b/packages/contracts/src/utils/types.ts
@@ -74,12 +74,22 @@ export interface Token {
swarmHash: string;
}
-export enum ExchangeContractErrs {
- ERROR_ORDER_EXPIRED,
- ERROR_ORDER_FULLY_FILLED,
- ERROR_ORDER_CANCELLED,
- ERROR_ROUNDING_ERROR_TOO_LARGE,
- ERROR_INSUFFICIENT_BALANCE_OR_ALLOWANCE,
+export enum ExchangeStatus {
+ INVALID,
+ SUCCESS,
+ ROUNDING_ERROR_TOO_LARGE,
+ INSUFFICIENT_BALANCE_OR_ALLOWANCE,
+ TAKER_ASSET_FILL_AMOUNT_TOO_LOW,
+ INVALID_SIGNATURE,
+ INVALID_SENDER,
+ INVALID_TAKER,
+ INVALID_MAKER,
+ ORDER_INVALID_MAKER_ASSET_AMOUNT,
+ ORDER_INVALID_TAKER_ASSET_AMOUNT,
+ ORDER_FILLABLE,
+ ORDER_EXPIRED,
+ ORDER_FULLY_FILLED,
+ ORDER_CANCELLED,
}
export enum ContractName {
@@ -143,3 +153,47 @@ export interface SignedTransaction {
data: string;
signature: string;
}
+
+export interface TransferAmountsByMatchOrders {
+ // Left Maker
+ amountBoughtByLeftMaker: BigNumber;
+ amountSoldByLeftMaker: BigNumber;
+ amountReceivedByLeftMaker: BigNumber;
+ feePaidByLeftMaker: BigNumber;
+ // Right Maker
+ amountBoughtByRightMaker: BigNumber;
+ amountSoldByRightMaker: BigNumber;
+ amountReceivedByRightMaker: BigNumber;
+ feePaidByRightMaker: BigNumber;
+ // Taker
+ amountReceivedByTaker: BigNumber;
+ feePaidByTakerLeft: BigNumber;
+ feePaidByTakerRight: BigNumber;
+ totalFeePaidByTaker: BigNumber;
+ // Fee Recipients
+ feeReceivedLeft: BigNumber;
+ feeReceivedRight: BigNumber;
+}
+
+export interface OrderInfo {
+ orderStatus: number;
+ orderHash: string;
+ orderTakerAssetFilledAmount: BigNumber;
+}
+
+export interface ERC20ProxyData {
+ assetProxyId: AssetProxyId;
+ tokenAddress: string;
+}
+
+export interface ERC721ProxyData {
+ assetProxyId: AssetProxyId;
+ tokenAddress: string;
+ tokenId: BigNumber;
+}
+
+export interface ProxyData {
+ assetProxyId: AssetProxyId;
+ tokenAddress?: string;
+ data?: any;
+}