Skip to content

Commit

Permalink
Added order forward compatibility with 2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Brechtpd committed Nov 27, 2018
1 parent 6afd89a commit bf7c270
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 8 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "protocol2-js",
"version": "0.2.20",
"version": "0.2.21",
"description": "loopring protocol simulator core lib",
"main": "index.ts",
"repository": {
Expand Down
23 changes: 22 additions & 1 deletion src/exchange_deserializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export class ExchangeDeserializer {
private dataOffset: number = 0;
private tableOffset: number = 0;

private zeroBytes32 = "0x" + "0".repeat(64);

constructor(context: Context) {
this.context = context;
}
Expand All @@ -40,7 +42,7 @@ export class ExchangeDeserializer {
// Calculate data pointers
const miningDataPtr = 8;
const orderDataPtr = miningDataPtr + 3 * 2;
const ringDataPtr = orderDataPtr + (24 * numOrders) * 2;
const ringDataPtr = orderDataPtr + (30 * numOrders) * 2;
const dataBlobPtr = ringDataPtr + (numRings * 9) + 32;

this.spendableList = [];
Expand Down Expand Up @@ -112,12 +114,21 @@ export class ExchangeDeserializer {
tokenBFeePercentage: this.nextUint16(),
tokenRecipient: this.nextAddress(),
walletSplitPercentage: this.nextUint16(),
tokenTypeS: this.nextUint16(),
tokenTypeB: this.nextUint16(),
tokenTypeFee: this.nextUint16(),
trancheS: this.nextBytes32(),
trancheB: this.nextBytes32(),
transferDataS: this.nextBytes(),
};

if (this.context) {
order.feeToken = order.feeToken ? order.feeToken : this.context.lrcAddress;
}
order.tokenRecipient = order.tokenRecipient ? order.tokenRecipient : order.owner;
order.trancheS = order.trancheS ? order.trancheS : this.zeroBytes32;
order.trancheB = order.trancheB ? order.trancheB : this.zeroBytes32;
order.transferDataS = order.transferDataS ? order.transferDataS : "0x";
return order;
}

Expand Down Expand Up @@ -192,6 +203,16 @@ export class ExchangeDeserializer {
}
}

private nextBytes32() {
const offset = this.getNextOffset() * 4;
if (offset !== 0) {
const data = "0x" + this.data.extractBytesX(this.dataOffset + offset, 32).toString("hex");
return data;
} else {
return "0x" + "0".repeat(64);
}
}

private toInt16(x: number) {
// Check if the number is negative
if (x >> 15 === 1) {
Expand Down
2 changes: 1 addition & 1 deletion src/expectThrow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export async function expectThrow(promise: Promise<any>, expectedRevertMessage?:
} catch (error) {

if (expectedRevertMessage) {
const message = error.message.search("revert " + expectedRevertMessage) >= 0;
const message = error.message.search(expectedRevertMessage) >= 0;
assert(message, "Expected throw with message " + expectedRevertMessage + ", got '" + error + "' instead");
} else {
const revert = error.message.search("revert") >= 0;
Expand Down
58 changes: 53 additions & 5 deletions src/order.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import { Context } from "./context";
import { getEIP712Message } from "./eip712";
import { ensure } from "./ensure";
import { MultiHashUtil } from "./multihash";
import { OrderInfo, Spendable } from "./types";
import { OrderInfo, Spendable, TokenType } from "./types";

export class OrderUtil {

private context: Context;

private zeroBytes32 = "0x" + "0".repeat(64);

constructor(context: Context) {
this.context = context;
}
Expand Down Expand Up @@ -51,6 +53,28 @@ export class OrderUtil {
valid = valid && ensure(order.validSince <= blockTimestamp, "order is too early to match");
valid = valid && ensure(order.validUntil ? order.validUntil > blockTimestamp : true, "order is expired");

// We only support ERC20 for now
valid = valid && ensure(
(order.tokenTypeS === TokenType.ERC20 && order.trancheS === this.zeroBytes32),
"invalid trancheS",
);
valid = valid && ensure(
(order.tokenTypeB === TokenType.ERC20 && order.trancheB === this.zeroBytes32),
"invalid trancheB",
);
valid = valid && ensure(
(order.tokenTypeFee === TokenType.ERC20),
"invalid tokenTypeFee",
);
valid = valid && ensure(
(order.tokenTypeS === TokenType.ERC20 && order.transferDataS === "0x"),
"invalid transferDataS",
);
// This emulates the revert in solidity with invalid enum values
assert(order.tokenTypeS < TokenType.COUNT, "invalid opcode");
assert(order.tokenTypeB < TokenType.COUNT, "invalid opcode");
assert(order.tokenTypeFee < TokenType.COUNT, "invalid opcode");

order.valid = order.valid && valid;
}

Expand Down Expand Up @@ -110,6 +134,12 @@ export class OrderUtil {
{ name: "tokenSFeePercentage", type: "uint16" },
{ name: "tokenBFeePercentage", type: "uint16" },
{ name: "allOrNone", type: "bool" },
{ name: "tokenTypeS", type: "uint8" },
{ name: "tokenTypeB", type: "uint8" },
{ name: "tokenTypeFee", type: "uint8" },
{ name: "trancheS", type: "bytes32" },
{ name: "trancheB", type: "bytes32" },
{ name: "transferDataS", type: "bytes" },
],
},
primaryType: "Order",
Expand All @@ -126,16 +156,22 @@ export class OrderUtil {
owner: order.owner,
tokenS: order.tokenS,
tokenB: order.tokenB,
dualAuthAddr: order.dualAuthAddr ? order.dualAuthAddr : "0x0",
broker: order.broker ? order.broker : "0x0",
orderInterceptor: order.orderInterceptor ? order.orderInterceptor : "0x0",
wallet: order.walletAddr ? order.walletAddr : "0x0",
dualAuthAddr: order.dualAuthAddr ? order.dualAuthAddr : "",
broker: order.broker ? order.broker : "",
orderInterceptor: order.orderInterceptor ? order.orderInterceptor : "",
wallet: order.walletAddr ? order.walletAddr : "",
tokenRecipient: order.tokenRecipient,
feeToken: order.feeToken,
walletSplitPercentage: order.walletSplitPercentage,
tokenSFeePercentage: order.tokenSFeePercentage,
tokenBFeePercentage: order.tokenBFeePercentage,
allOrNone: order.allOrNone,
tokenTypeS: order.tokenTypeS ? order.tokenTypeS : TokenType.ERC20,
tokenTypeB: order.tokenTypeB ? order.tokenTypeB : TokenType.ERC20,
tokenTypeFee: order.tokenTypeFee ? order.tokenTypeFee : TokenType.ERC20,
trancheS: order.trancheS ? order.trancheS : "",
trancheB: order.trancheB ? order.trancheB : "",
transferDataS: order.transferDataS ? order.transferDataS : "",
},
};
return typedData;
Expand Down Expand Up @@ -163,6 +199,7 @@ export class OrderUtil {

public toOrderBookSubmitParams(orderInfo: OrderInfo) {
const emptyAddr = "0x" + "0".repeat(40);
const zeroBytes32 = "0x" + "0".repeat(64);

const data = new Bitstream();
data.addAddress(orderInfo.owner, 32);
Expand All @@ -183,6 +220,17 @@ export class OrderUtil {
data.addNumber(orderInfo.tokenBFeePercentage ? orderInfo.tokenBFeePercentage : 0, 32);
data.addAddress(orderInfo.tokenRecipient ? orderInfo.tokenRecipient : orderInfo.owner, 32);
data.addNumber(orderInfo.walletSplitPercentage ? orderInfo.walletSplitPercentage : 0, 32);
data.addNumber(orderInfo.tokenTypeS ? orderInfo.tokenTypeS : TokenType.ERC20, 32);
data.addNumber(orderInfo.tokenTypeB ? orderInfo.tokenTypeB : TokenType.ERC20, 32);
data.addNumber(orderInfo.tokenTypeFee ? orderInfo.tokenTypeFee : TokenType.ERC20, 32);
data.addHex(orderInfo.trancheS ? orderInfo.trancheS : zeroBytes32);
data.addHex(orderInfo.trancheB ? orderInfo.trancheB : zeroBytes32);
if (orderInfo.transferDataS) {
data.addNumber((orderInfo.transferDataS.length - 2) / 2, 32);
data.addHex(orderInfo.transferDataS);
} else {
data.addNumber(0, 32);
}

return data.getData();
}
Expand Down
25 changes: 25 additions & 0 deletions src/rings_generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export class RingsGenerator {
private SERIALIZATION_VERSION = 0;
private ORDER_VERSION = 0;

private zeroAddress = "0x" + "0".repeat(64);

constructor(context: Context) {
this.context = context;
this.orderUtil = new OrderUtil(context);
Expand Down Expand Up @@ -299,6 +301,29 @@ export class RingsGenerator {
}

param.tables.addNumber(order.walletSplitPercentage ? order.walletSplitPercentage : 0, 2);

param.tables.addNumber(order.tokenTypeS, 2);
param.tables.addNumber(order.tokenTypeB, 2);
param.tables.addNumber(order.tokenTypeFee, 2);

if (order.trancheS && order.trancheS !== "0x0" && order.trancheS !== this.zeroAddress) {
this.insertOffset(param, param.data.addHex(order.trancheS, false));
} else {
this.insertDefault(param);
}

if (order.trancheB && order.trancheB !== "0x0" && order.trancheB !== this.zeroAddress) {
this.insertOffset(param, param.data.addHex(order.trancheB, false));
} else {
this.insertDefault(param);
}

if (order.transferDataS && order.transferDataS !== "0x" && order.transferDataS !== "") {
this.insertOffset(param, param.data.addHex(this.createBytes(order.transferDataS), false));
this.addPadding(param);
} else {
this.insertDefault(param);
}
}

private xor(s1: string, s2: string, numBytes: number) {
Expand Down
12 changes: 12 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export enum SignAlgorithm {
None = 255, // Do not sign
}

export enum TokenType {
ERC20 = 0,
COUNT = 1,
}

export interface Spendable {
initialized?: boolean;
amount?: BigNumber;
Expand Down Expand Up @@ -53,6 +58,13 @@ export interface OrderInfo {
tokenRecipient?: string;
walletSplitPercentage?: number;

tokenTypeS?: TokenType;
tokenTypeB?: TokenType;
tokenTypeFee?: TokenType;
trancheS?: string;
trancheB?: string;
transferDataS?: string;

// helper field
P2P?: boolean;
filledAmountS?: BigNumber;
Expand Down

0 comments on commit bf7c270

Please sign in to comment.