Skip to content

Commit dafa3f0

Browse files
committed
SerializeOrders: Add order serialization
1 parent 94fba62 commit dafa3f0

File tree

4 files changed

+137
-8
lines changed

4 files changed

+137
-8
lines changed

src/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
import {
1919
generateTimestamp,
2020
generateSalt,
21+
generateSerializedOrders,
2122
hashOrderHex
2223
} from './orders';
2324
import {
@@ -182,6 +183,16 @@ export class SetProtocolUtils {
182183
return parseSignatureHexAsRSV(signature);
183184
}
184185

186+
/**
187+
* Generates a byte string representing serialized exchange orders across different exchanges.
188+
* @param makerTokenAddress Address of the token used to pay for the order
189+
* @param orders Array of orders from various exchanges
190+
* @return Buffer with all exchange orders formatted and concatenated
191+
*/
192+
public generateSerializedOrders(makerTokenAddress: Address, orders: object[]): Bytes32 {
193+
return generateSerializedOrders(makerTokenAddress, orders, this.web3);
194+
}
195+
185196
/**
186197
* Signs a message and returns it's elliptic curve signature
187198
* @param message Data to sign

src/orders.ts

Lines changed: 120 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,33 @@
1-
import * as _ from 'lodash';
2-
import * as ethUtil from 'ethereumjs-util';
1+
/*
2+
Copyright 2018 Set Labs Inc.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
'use strict';
18+
319
import { BigNumber } from 'bignumber.js';
20+
import * as ethUtil from 'ethereumjs-util';
21+
import * as _ from 'lodash';
22+
import * as Web3 from 'web3';
423

524
import { constants } from './constants';
6-
import { bufferObjectWithProperties } from './encoding';
7-
import { IssuanceOrder, SolidityTypes } from './types';
25+
import { paddedBufferForPrimitive, bufferObjectWithProperties } from './encoding';
26+
import { Address, Bytes32, IssuanceOrder, SolidityTypes, TakerWalletOrder } from './types';
827

28+
interface Exchanges {
29+
[exchangeId: string]: TakerWalletOrder[];
30+
}
931

1032
export function generateTimestamp(minutes: number): BigNumber {
1133
const timeToExpiration = minutes * 60 * 1000;
@@ -42,3 +64,97 @@ export function hashOrderHex(order: IssuanceOrder): string {
4264

4365
return ethUtil.bufferToHex(buffer);
4466
}
67+
68+
/* ============ Order Data Serialization ============ */
69+
70+
/**
71+
* Generates a byte string representing serialized exchange orders across different exchanges.
72+
*
73+
* @param makerTokenAddress Address of the token used to pay for the order
74+
* @param orders Array of orders from various exchanges
75+
* @param web3 web3 instance instantiated with `new Web3(provider);`
76+
* @return Buffer with all exchange orders formatted and concatenated
77+
*/
78+
79+
export function generateSerializedOrders(
80+
makerTokenAddress: Address,
81+
orders: object[],
82+
web3: Web3,
83+
): Bytes32 {
84+
const orderBuffer: Buffer[] = [];
85+
// Sort exchange orders by exchange
86+
const exchanges: Exchanges = {
87+
'1': [],
88+
'2': [],
89+
'3': [],
90+
};
91+
_.forEach(orders, (order: TakerWalletOrder) => {
92+
const { exchange } = order;
93+
const exchangeOrders: object[] = exchanges[exchange];
94+
exchangeOrders.push(order);
95+
});
96+
// Loop through all exchange orders and create buffers
97+
_.forEach(exchanges, (exchangeOrders, key) => {
98+
if (key === '1') { // Todo: Replace with set-protocol-contracts constants
99+
// Handle Zero Ex
100+
} else if (key === '2') {
101+
// Handle Kyber Network
102+
} else if (key === '3') {
103+
orderBuffer.push(generateTakerWalletOrdersBuffer(makerTokenAddress, exchangeOrders, web3));
104+
}
105+
});
106+
return ethUtil.bufferToHex(Buffer.concat(orderBuffer));
107+
}
108+
109+
/* ============ Taker Wallet Order Functions ============ */
110+
111+
/**
112+
* Takes a taker wallet order object and turns it into a buffer.
113+
*
114+
* @param takerTokenAddress Address of the token the taker will fill in the taker wallet order
115+
* @param takerTokenAmount Amount of tokens the taker will fill in the order
116+
* @param web3 web3 instance instantiated with `new Web3(provider);`
117+
* @return Taker wallet order as a buffer
118+
*/
119+
120+
export function takerWalletOrderToBuffer(
121+
takerTokenAddress: Address,
122+
takerTokenAmount: BigNumber,
123+
web3: Web3,
124+
): Buffer {
125+
const takerWalletOrder: Buffer[] = [];
126+
takerWalletOrder.push(paddedBufferForPrimitive(takerTokenAddress));
127+
takerWalletOrder.push(paddedBufferForPrimitive(web3.toHex(takerTokenAmount)));
128+
return Buffer.concat(takerWalletOrder);
129+
}
130+
131+
/**
132+
* Takes taker wallet orders and generates a buffer representing all orders the
133+
* taker can fill directly from their wallet.
134+
*
135+
* @param makerTokenAddress Address of the token used to pay for the order
136+
* @param orders Array of TakerWalletOrders
137+
* @param web3 web3 instance instantiated with `new Web3(provider);`
138+
* @return Entire taker wallet orders data as a buffer
139+
*/
140+
141+
export function generateTakerWalletOrdersBuffer(
142+
makerTokenAddress: Address,
143+
orders: TakerWalletOrder[],
144+
web3: Web3,
145+
): Buffer {
146+
// Generate header for taker wallet order
147+
const takerOrderHeader: Buffer[] = [
148+
paddedBufferForPrimitive(3), // Todo: Replace with set-protocol-contracts constants
149+
paddedBufferForPrimitive(orders.length), // Include the number of orders as part of header
150+
paddedBufferForPrimitive(makerTokenAddress),
151+
paddedBufferForPrimitive(0), // Taker wallet orders do not take any maker token to execute
152+
];
153+
// Turn all taker wallet orders to buffers
154+
const takerOrderBody: Buffer[] = _.map(orders, ({takerTokenAddress, takerTokenAmount}) =>
155+
takerWalletOrderToBuffer(takerTokenAddress, takerTokenAmount, web3));
156+
return Buffer.concat([
157+
Buffer.concat(takerOrderHeader),
158+
Buffer.concat(takerOrderBody),
159+
]);
160+
}

src/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,9 @@ export enum SolidityTypes {
4141
AddressArray = 'address[]',
4242
UintArray = 'uint256[]',
4343
}
44+
45+
export interface TakerWalletOrder {
46+
exchange: number;
47+
takerTokenAddress: Address;
48+
takerTokenAmount: BigNumber;
49+
}

yarn.lock

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2752,10 +2752,6 @@ lru-cache@^4.0.1:
27522752
pseudomap "^1.0.2"
27532753
yallist "^2.1.2"
27542754

2755-
make-promises-safe@^1.1.0:
2756-
version "1.1.0"
2757-
resolved "https://registry.yarnpkg.com/make-promises-safe/-/make-promises-safe-1.1.0.tgz#b4d28c61ef8ad5502f38dbb3a0ee89627f76ad61"
2758-
27592755
map-cache@^0.2.2:
27602756
version "0.2.2"
27612757
resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"

0 commit comments

Comments
 (0)