Atomic Order Matching - Tests
This commit is contained in:
@@ -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;
|
||||
},
|
||||
};
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
},
|
||||
};
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user