aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contracts/src/utils
diff options
context:
space:
mode:
authorGreg Hysen <greg.hysen@gmail.com>2018-05-11 05:22:49 +0800
committerGreg Hysen <greg.hysen@gmail.com>2018-05-19 08:01:05 +0800
commit9b1015bbce81b3f2a245e3dab6eea7c9028ce93b (patch)
tree3c698977176d907e04a8cfe0716f5d1f36167398 /packages/contracts/src/utils
parenta4c821eb60c227df4512d6c24ce0e5239b8bb6ce (diff)
downloaddexon-0x-contracts-9b1015bbce81b3f2a245e3dab6eea7c9028ce93b.tar.gz
dexon-0x-contracts-9b1015bbce81b3f2a245e3dab6eea7c9028ce93b.tar.zst
dexon-0x-contracts-9b1015bbce81b3f2a245e3dab6eea7c9028ce93b.zip
Atomic Order Matching - Tests
Diffstat (limited to 'packages/contracts/src/utils')
-rw-r--r--packages/contracts/src/utils/asset_proxy_utils.ts74
-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.ts48
4 files changed, 147 insertions, 6 deletions
diff --git a/packages/contracts/src/utils/asset_proxy_utils.ts b/packages/contracts/src/utils/asset_proxy_utils.ts
index dc31c3497..9a26a9ca7 100644
--- a/packages/contracts/src/utils/asset_proxy_utils.ts
+++ b/packages/contracts/src/utils/asset_proxy_utils.ts
@@ -8,6 +8,9 @@ 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,28 @@ export const assetProxyUtils = {
const encodedMetadataHex = ethUtil.bufferToHex(encodedMetadata);
return encodedMetadataHex;
},
+ decodeERC20ProxyData(proxyData: string): string /* tokenAddress */ {
+ 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);
+ return tokenAddress;
+ },
encodeERC721ProxyData(tokenAddress: string, tokenId: BigNumber): string {
const encodedAssetProxyId = assetProxyUtils.encodeAssetProxyId(AssetProxyId.ERC721);
const encodedAddress = assetProxyUtils.encodeAddress(tokenAddress);
@@ -36,4 +73,41 @@ export const assetProxyUtils = {
const encodedMetadataHex = ethUtil.bufferToHex(encodedMetadata);
return encodedMetadataHex;
},
+ decodeERC721ProxyData(proxyData: string): [string /* tokenAddress */, BigNumber /* tokenId */] {
+ 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);
+ return [tokenAddress, tokenId];
+ },
+ 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;
+ },
};
diff --git a/packages/contracts/src/utils/exchange_wrapper.ts b/packages/contracts/src/utils/exchange_wrapper.ts
index 27fdd698f..6d36198f2 100644
--- a/packages/contracts/src/utils/exchange_wrapper.ts
+++ b/packages/contracts/src/utils/exchange_wrapper.ts
@@ -231,4 +231,26 @@ export class ExchangeWrapper {
tx.logs = _.map(tx.logs, log => this._logDecoder.decodeLogOrThrow(log));
return tx;
}
+ public async getOrderInfoAsync(
+ signedOrder: SignedOrder,
+ ): Promise<[number /* orderStatus */, string /* orderHash */, BigNumber /* orderTakerAssetAmountFilled */]> {
+ const orderInfo: [number, string, BigNumber] = await this._exchange.getOrderInfo.callAsync(signedOrder);
+ 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;
+ }
}
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..ce7fbcbe1 100644
--- a/packages/contracts/src/utils/types.ts
+++ b/packages/contracts/src/utils/types.ts
@@ -74,12 +74,27 @@ 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 {
+ /// Default Status ///
+ INVALID, // General invalid status
+
+ /// General Exchange Statuses ///
+ SUCCESS, // Indicates a successful operation
+ ROUNDING_ERROR_TOO_LARGE, // Rounding error too large
+ INSUFFICIENT_BALANCE_OR_ALLOWANCE, // Insufficient balance or allowance for token transfer
+ TAKER_ASSET_FILL_AMOUNT_TOO_LOW, // takerAssetFillAmount is <= 0
+ INVALID_SIGNATURE, // Invalid signature
+ INVALID_SENDER, // Invalid sender
+ INVALID_TAKER, // Invalid taker
+ INVALID_MAKER, // Invalid maker
+
+ /// Order State Statuses ///
+ ORDER_INVALID_MAKER_ASSET_AMOUNT, // Order does not have a valid maker asset amount
+ ORDER_INVALID_TAKER_ASSET_AMOUNT, // Order does not have a valid taker asset amount
+ ORDER_FILLABLE, // Order is fillable
+ ORDER_EXPIRED, // Order has already expired
+ ORDER_FULLY_FILLED, // Order is fully filled
+ ORDER_CANCELLED, // Order has been cancelled
}
export enum ContractName {
@@ -143,3 +158,24 @@ 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;
+}