Skip to content

Commit a82d9de

Browse files
author
Peter Petrovics
authored
Merge pull request #13 from Augmint/exchange-opt
Exchange optimization
2 parents 6d9cc1c + 45712f1 commit a82d9de

File tree

2 files changed

+40
-44
lines changed

2 files changed

+40
-44
lines changed

Diff for: contracts/Exchange.sol

+35-34
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
TODO:
66
- deduct fee
77
- consider take funcs (frequent rate changes with takeBuyToken? send more and send back remainder?)
8-
- uint32 for addedTime?
98
*/
109
pragma solidity 0.4.19;
1110

@@ -19,57 +18,58 @@ contract Exchange {
1918
uint public constant CHUNK_SIZE = 100;
2019

2120
struct Order {
22-
uint index;
21+
uint64 index;
2322
address maker;
24-
uint addedTime;
2523

2624
// tokens per ether
27-
uint price;
25+
uint32 price;
2826

2927
// buy order: amount in wei
3028
// sell order: token amount
3129
uint amount;
3230
}
3331

34-
Order[] public buyTokenOrders;
35-
Order[] public sellTokenOrders;
32+
uint64 public orderCount;
33+
mapping(uint64 => Order) public buyTokenOrders;
34+
mapping(uint64 => Order) public sellTokenOrders;
3635

37-
uint[] private activeBuyOrders;
38-
uint[] private activeSellOrders;
36+
uint64[] private activeBuyOrders;
37+
uint64[] private activeSellOrders;
3938

4039
/* used to stop executing matchMultiple when running out of gas.
4140
actual is much less, just leaving enough matchMultipleOrders() to finish TODO: fine tune & test it*/
4241
uint32 private constant ORDER_MATCH_WORST_GAS = 100000;
4342

44-
event NewOrder(uint indexed orderId, address indexed maker, uint price, uint tokenAmount,
43+
event NewOrder(uint64 indexed orderId, address indexed maker, uint32 price, uint tokenAmount,
4544
uint weiAmount);
4645

47-
event OrderFill(address indexed tokenBuyer, address indexed tokenSeller, uint buyTokenOrderId,
48-
uint sellTokenOrderId, uint price, uint weiAmount, uint tokenAmount);
46+
event OrderFill(address indexed tokenBuyer, address indexed tokenSeller, uint64 buyTokenOrderId,
47+
uint64 sellTokenOrderId, uint32 price, uint weiAmount, uint tokenAmount);
4948

50-
event CancelledOrder(uint indexed orderId, address indexed maker, uint tokenAmount, uint weiAmount);
49+
event CancelledOrder(uint64 indexed orderId, address indexed maker, uint tokenAmount, uint weiAmount);
5150

5251
function Exchange(AugmintTokenInterface _augmintToken) public {
5352
augmintToken = _augmintToken;
5453
}
5554

56-
function placeBuyTokenOrder(uint price) external payable returns (uint orderId) {
55+
function placeBuyTokenOrder(uint32 price) external payable returns (uint64 orderId) {
5756
require(price > 0);
5857
require(msg.value > 0);
5958

60-
orderId = buyTokenOrders.push(Order(activeBuyOrders.length, msg.sender, now, price, msg.value)) - 1;
59+
orderId = ++orderCount;
60+
buyTokenOrders[orderId] = Order(uint64(activeBuyOrders.length), msg.sender, price, msg.value);
6161
activeBuyOrders.push(orderId);
6262

6363
NewOrder(orderId, msg.sender, price, 0, msg.value);
6464
}
6565

6666
/* this function requires previous approval to transfer tokens */
67-
function placeSellTokenOrder(uint price, uint tokenAmount) external returns (uint orderId) {
67+
function placeSellTokenOrder(uint32 price, uint tokenAmount) external returns (uint orderId) {
6868
augmintToken.transferFrom(msg.sender, this, tokenAmount);
6969
return _placeSellTokenOrder(msg.sender, price, tokenAmount);
7070
}
7171

72-
function cancelBuyTokenOrder(uint buyTokenId) external {
72+
function cancelBuyTokenOrder(uint64 buyTokenId) external {
7373
Order storage order = buyTokenOrders[buyTokenId];
7474
require(order.maker == msg.sender);
7575

@@ -82,7 +82,7 @@ contract Exchange {
8282
CancelledOrder(buyTokenId, msg.sender, 0, amount);
8383
}
8484

85-
function cancelSellTokenOrder(uint sellTokenId) external {
85+
function cancelSellTokenOrder(uint64 sellTokenId) external {
8686
Order storage order = sellTokenOrders[sellTokenId];
8787
require(order.maker == msg.sender);
8888

@@ -99,15 +99,15 @@ contract Exchange {
9999
trade price meets in the middle
100100
reverts if any of the orders have been removed
101101
*/
102-
function matchOrders(uint buyTokenId, uint sellTokenId) external {
102+
function matchOrders(uint64 buyTokenId, uint64 sellTokenId) external {
103103
_fillOrder(buyTokenId, sellTokenId);
104104
}
105105

106106
/* matches as many orders as possible from the passed orders
107107
Runs as long as gas is available for the call.
108108
Stops if any match is invalid (case when any of the orders removed after client generated the match list sent)
109109
*/
110-
function matchMultipleOrders(uint[] buyTokenIds, uint[] sellTokenIds) external returns(uint matchCount) {
110+
function matchMultipleOrders(uint64[] buyTokenIds, uint64[] sellTokenIds) external returns(uint matchCount) {
111111
uint len = buyTokenIds.length;
112112
require(len == sellTokenIds.length);
113113
for (uint i = 0; i < len && msg.gas > ORDER_MATCH_WORST_GAS; i++) {
@@ -121,20 +121,20 @@ contract Exchange {
121121
}
122122

123123
// returns CHUNK_SIZE orders starting from offset
124-
// orders are encoded as [id, maker, addedTime, price, amount]
125-
function getActiveBuyOrders(uint offset) external view returns (uint[5][CHUNK_SIZE] response) {
124+
// orders are encoded as [id, maker, price, amount]
125+
function getActiveBuyOrders(uint offset) external view returns (uint[4][CHUNK_SIZE] response) {
126126
for (uint8 i = 0; i < CHUNK_SIZE && i + offset < activeBuyOrders.length; i++) {
127-
uint orderId = activeBuyOrders[offset + i];
127+
uint64 orderId = activeBuyOrders[offset + i];
128128
Order storage order = buyTokenOrders[orderId];
129-
response[i] = [orderId, uint(order.maker), order.addedTime, order.price, order.amount];
129+
response[i] = [orderId, uint(order.maker), order.price, order.amount];
130130
}
131131
}
132132

133-
function getActiveSellOrders(uint offset) external view returns (uint[5][CHUNK_SIZE] response) {
133+
function getActiveSellOrders(uint offset) external view returns (uint[4][CHUNK_SIZE] response) {
134134
for (uint8 i = 0; i < CHUNK_SIZE && i + offset < activeSellOrders.length; i++) {
135-
uint orderId = activeSellOrders[offset + i];
135+
uint64 orderId = activeSellOrders[offset + i];
136136
Order storage order = sellTokenOrders[orderId];
137-
response[i] = [orderId, uint(order.maker), order.addedTime, order.price, order.amount];
137+
response[i] = [orderId, uint(order.maker), order.price, order.amount];
138138
}
139139
}
140140

@@ -146,17 +146,17 @@ contract Exchange {
146146
*/
147147
function transferNotification(address maker, uint tokenAmount, uint price) public {
148148
require(msg.sender == address(augmintToken));
149-
_placeSellTokenOrder(maker, price, tokenAmount);
149+
_placeSellTokenOrder(maker, uint32(price), tokenAmount);
150150
}
151151

152-
function _fillOrder(uint buyTokenId, uint sellTokenId) private {
152+
function _fillOrder(uint64 buyTokenId, uint64 sellTokenId) private {
153153
Order storage buy = buyTokenOrders[buyTokenId];
154154
Order storage sell = sellTokenOrders[sellTokenId];
155155

156156
require(buy.price >= sell.price);
157157

158158
// meet in the middle
159-
uint price = buy.price.add(sell.price).div(2);
159+
uint price = uint(buy.price).add(sell.price).div(2);
160160

161161
uint sellWei = sell.amount.mul(1 ether).div(price);
162162

@@ -184,16 +184,17 @@ contract Exchange {
184184
sell.maker.transfer(tradedWei);
185185

186186
OrderFill(buy.maker, sell.maker, buyTokenId,
187-
sellTokenId, price, tradedWei, tradedTokens);
187+
sellTokenId, uint32(price), tradedWei, tradedTokens);
188188
}
189189

190190

191-
function _placeSellTokenOrder(address maker, uint price, uint tokenAmount)
192-
private returns (uint orderId) {
191+
function _placeSellTokenOrder(address maker, uint32 price, uint tokenAmount)
192+
private returns (uint64 orderId) {
193193
require(price > 0);
194194
require(tokenAmount > 0);
195195

196-
orderId = sellTokenOrders.push(Order(activeSellOrders.length, maker, now, price, tokenAmount)) - 1;
196+
orderId = ++orderCount;
197+
sellTokenOrders[orderId] = Order(uint64(activeSellOrders.length), maker, price, tokenAmount);
197198
activeSellOrders.push(orderId);
198199

199200
NewOrder(orderId, maker, price, tokenAmount, 0);
@@ -207,7 +208,7 @@ contract Exchange {
207208
_removeOrder(activeSellOrders, order.index);
208209
}
209210

210-
function _removeOrder(uint[] storage orders, uint index) private {
211+
function _removeOrder(uint64[] storage orders, uint64 index) private {
211212
if (index < orders.length - 1) {
212213
orders[index] = orders[orders.length - 1];
213214
}

Diff for: test/helpers/exchangeTestHelpers.js

+5-10
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ async function newOrder(testInstance, order) {
9393
assert.equal(state.sellCount, expSellCount, "sellCount should be set");
9494
assert.equal(actualOrder.id, order.id, "orderId should be set in contract's order array");
9595
assert.equal(actualOrder.maker, order.maker, "maker should be the userAccount in contract's order array");
96-
// TODO: assert order.addedTime
9796
assert.equal(actualOrder.price, order.price, "price should be set in contract's order array");
9897
assert.equal(
9998
actualOrder.amount.toString(),
@@ -327,21 +326,19 @@ function parseOrder(order) {
327326
return {
328327
index: order[0],
329328
maker: order[1],
330-
addedTime: order[2].toNumber(),
331-
price: order[3].toNumber(),
332-
amount: order[4]
329+
price: order[2].toNumber(),
330+
amount: order[3]
333331
};
334332
}
335333

336334
function parseOrders(orderType, orders) {
337-
return orders.filter(order => order[4].toNumber() != 0).map(function(order) {
335+
return orders.filter(order => order[3].toNumber() != 0).map(function(order) {
338336
return {
339337
orderType: orderType,
340338
id: order[0].toNumber(),
341339
maker: "0x" + order[1].toString(16),
342-
addedTime: order[2].toNumber(),
343-
price: order[3].toNumber(),
344-
amount: order[4]
340+
price: order[2].toNumber(),
341+
amount: order[3]
345342
};
346343
});
347344
}
@@ -375,7 +372,6 @@ async function printOrderBook(_limit) {
375372
const order = await getSellTokenOrder(i);
376373
console.log(
377374
`SELL token: ACE/ETH: ${order.price / 10000} amount: ${order.amount.toString() / 10000} ACE` +
378-
` ${moment.unix(order.addedTime).format("HH:mm:ss")}` +
379375
` orderIdx: ${i} orderId: ${order.id} acc: ${order.maker}`
380376
);
381377
}
@@ -384,7 +380,6 @@ async function printOrderBook(_limit) {
384380
const order = await getBuyTokenOrder(i);
385381
console.log(
386382
` BUY token: ACE/EUR: ${order.price / 10000} amount: ${web3.fromWei(order.amount)} ETH` +
387-
` ${moment.unix(order.addedTime).format("HH:mm:ss")}` +
388383
` orderIdx: ${i} orderId: ${order.id} acc: ${order.maker}`
389384
);
390385
}

0 commit comments

Comments
 (0)