Skip to content
This repository was archived by the owner on Mar 19, 2019. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 74 additions & 47 deletions contracts/Exchange.sol
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ contract Exchange is IExchange {

struct Order {
address owner;
address signer;
address broker;
address tokenS;
address tokenB;
address wallet;
Expand Down Expand Up @@ -100,7 +100,7 @@ contract Exchange is IExchange {
uint[6][] valuesList;
uint8[] optionList;
bytes[] sigList;
address miner;
address feeRecipient;
address interceptor;
uint8 feeSelections;
uint64 ringIndex;
Expand Down Expand Up @@ -181,28 +181,22 @@ contract Exchange is IExchange {
0
);
require(
msg.sender == order.signer,
"cancelOrder not submitted by signer"
tx.origin == order.broker,
"cancelOrder not submitted by broker"
);

bytes32 orderHash = calculateOrderHash(order);

MultihashUtil.verifySignature(
order.signer,
order.broker,
orderHash,
sig
);

if (order.signer != order.owner) {
IBrokerRegistry brokerRegistry = IBrokerRegistry(brokerRegistryAddress);
bool registered;
address tracker;
(registered, tracker) = brokerRegistry.getBroker(
order.owner,
order.signer
);
require(registered, "invalid broker");
}
order.brokerInterceptor = verifyAuthenticationGetInterceptor(
order.owner,
order.broker
);

// For AON orders, must cancel it as a whole.
if (order.optAllOrNone) {
Expand All @@ -214,60 +208,77 @@ contract Exchange is IExchange {

emit OrderCancelled(
order.owner,
tx.origin,
orderHash,
cancelAmount
);
}

function cancelAllOrdersByTradingPair(
address owner,
address token1,
address token2,
uint cutoff
)
external
{
verifyAuthenticationGetInterceptor(owner, tx.origin);

uint t = (cutoff == 0 || cutoff >= block.timestamp) ? block.timestamp : cutoff;

bytes20 tokenPair = bytes20(token1) ^ bytes20(token2);
ITokenTransferDelegate delegate = ITokenTransferDelegate(delegateAddress);

require(
delegate.tradingPairCutoffs(msg.sender, tokenPair) < t,
delegate.tradingPairCutoffs(owner, tokenPair) < t,
"cutoff too small"
);

delegate.setTradingPairCutoffs(tokenPair, t);
delegate.setTradingPairCutoffs(
owner,
tokenPair,
t
);

emit OrdersCancelled(
msg.sender,
owner,
tx.origin,
token1,
token2,
t
);
}

function cancelAllOrders(
uint cutoff
address owner,
uint cutoff
)
external
{
verifyAuthenticationGetInterceptor(owner, tx.origin);

uint t = (cutoff == 0 || cutoff >= block.timestamp) ? block.timestamp : cutoff;
ITokenTransferDelegate delegate = ITokenTransferDelegate(delegateAddress);

require(
delegate.cutoffs(msg.sender) < t,
delegate.cutoffs(owner) < t,
"cutoff too small"
);

delegate.setCutoffs(t);
emit AllOrdersCancelled(msg.sender, t);
delegate.setCutoffs(owner, t);
emit AllOrdersCancelled(
owner,
tx.origin,
t
);
}

function submitRing(
address[6][] addressesList,
uint[6][] valuesList,
uint8[] optionList,
bytes[] sigList,
address miner,
address feeRecipient,
address interceptor,
uint8 feeSelections
)
Expand All @@ -278,7 +289,7 @@ contract Exchange is IExchange {
valuesList,
optionList,
sigList,
miner,
feeRecipient,
interceptor,
feeSelections,
ringIndex,
Expand Down Expand Up @@ -325,9 +336,11 @@ contract Exchange is IExchange {
Context ctx
)
private
pure
view
{
require(ctx.miner != 0x0, "bad miner");
if (ctx.feeRecipient == 0x0) {
ctx.feeRecipient = tx.origin;
}

require(
ctx.ringSize == ctx.addressesList.length,
Expand Down Expand Up @@ -408,29 +421,23 @@ contract Exchange is IExchange {
order.orderHash = calculateOrderHash(order);

MultihashUtil.verifySignature(
order.signer,
order.broker,
order.orderHash,
ctx.sigList[i]
);

if (order.signer != order.owner) {
IBrokerRegistry brokerRegistry = IBrokerRegistry(brokerRegistryAddress);
bool authenticated;
(authenticated, order.brokerInterceptor) = brokerRegistry.getBroker(
order.owner,
order.signer
);

require(authenticated, "invalid broker");
}
order.brokerInterceptor = verifyAuthenticationGetInterceptor(
order.owner,
order.broker
);

ctx.orders[i] = order;
ctx.ringHash ^= order.orderHash;
}

ctx.ringHash = keccak256(
ctx.ringHash,
ctx.miner,
ctx.feeRecipient,
ctx.feeSelections
);
}
Expand Down Expand Up @@ -459,7 +466,7 @@ contract Exchange is IExchange {
}

/// @dev Verify the ringHash has been signed with each order's auth private
/// keys as well as the miner's private key.
/// keys.
function verifyRingSignatures(
Context ctx
)
Expand Down Expand Up @@ -589,7 +596,7 @@ contract Exchange is IExchange {
ctx.delegate,
order.tokenS,
order.owner,
order.signer,
order.broker,
order.brokerInterceptor
);

Expand Down Expand Up @@ -646,7 +653,7 @@ contract Exchange is IExchange {
}

/// @dev Calculate each order's `lrcFee` and `lrcRewrard` and splict how much
/// of `fillAmountS` shall be paid to matching order or miner as margin
/// of `fillAmountS` shall be paid to matching order or fee recipient as margin
/// split.
function calculateRingFees(
Context ctx
Expand All @@ -672,7 +679,7 @@ contract Exchange is IExchange {
ctx.delegate,
lrcTokenAddress,
order.owner,
order.signer,
order.broker,
order.brokerInterceptor
);

Expand Down Expand Up @@ -718,7 +725,7 @@ contract Exchange is IExchange {
minerLrcSpendable = getSpendable(
ctx.delegate,
lrcTokenAddress,
ctx.miner,
tx.origin,
0x0,
0x0
);
Expand Down Expand Up @@ -781,7 +788,7 @@ contract Exchange is IExchange {

// Store owner and tokenS of every order
batch[p++] = bytes32(order.owner);
batch[p++] = bytes32(order.signer);
batch[p++] = bytes32(order.broker);
batch[p++] = bytes32(order.brokerInterceptor);
batch[p++] = bytes32(order.tokenS);

Expand Down Expand Up @@ -811,14 +818,16 @@ contract Exchange is IExchange {

ctx.delegate.batchUpdateHistoryAndTransferTokens(
lrcTokenAddress,
ctx.miner,
tx.origin,
ctx.feeRecipient,
historyBatch,
batch
);

emit RingMined(
ctx.ringIndex,
ctx.miner,
tx.origin,
ctx.feeRecipient,
fills
);
}
Expand Down Expand Up @@ -951,7 +960,7 @@ contract Exchange is IExchange {
return keccak256(
delegateAddress,
order.owner,
order.signer,
order.broker,
order.tokenS,
order.tokenB,
order.wallet,
Expand All @@ -978,4 +987,22 @@ contract Exchange is IExchange {
ITokenTransferDelegate delegate = ITokenTransferDelegate(delegateAddress);
return delegate.tradingPairCutoffs(orderOwner, tokenPair);
}

function verifyAuthenticationGetInterceptor(
address owner,
address signer
)
private
view
returns (address brokerInterceptor)
{
if (signer == owner) {
brokerInterceptor = 0x0;
} else {
IBrokerRegistry brokerRegistry = IBrokerRegistry(brokerRegistryAddress);
bool authenticated;
(authenticated, brokerInterceptor) = brokerRegistry.getBroker(owner, signer);
require(authenticated, "broker unauthenticated");
}
}
}
24 changes: 15 additions & 9 deletions contracts/IExchange.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,31 +39,35 @@ contract IExchange {

event RingMined(
uint _ringIndex,
address indexed _miner,
address indexed _broker,
address indexed _feeRecipient,
Fill[] _fills
);

event OrderCancelled(
address indexed _address,
address indexed _owner,
address indexed _broker,
bytes32 _orderHash,
uint _amountCancelled
);

event AllOrdersCancelled(
address indexed _address,
address indexed _owner,
address indexed _broker,
uint _cutoff
);

event OrdersCancelled(
address indexed _address,
address indexed _owner,
address indexed _broker,
address _token1,
address _token2,
uint _cutoff
);

/// @dev Cancel a order. cancel amount(amountS or amountB) can be specified
/// in values.
/// @param addresses owner, signer, tokenS, tokenB, wallet, authAddr,
/// @param addresses owner, broker, tokenS, tokenB, wallet, authAddr,
/// and order interceptor
/// @param values amountS, amountB, validSince (second),
/// validUntil (second), lrcFee, and cancelAmount.
Expand All @@ -84,6 +88,7 @@ contract IExchange {
/// @param cutoff The cutoff timestamp, will default to `block.timestamp`
/// if it is 0.
function cancelAllOrdersByTradingPair(
address owner,
address token1,
address token2,
uint cutoff
Expand All @@ -96,12 +101,13 @@ contract IExchange {
/// @param cutoff The cutoff timestamp, will default to `block.timestamp`
/// if it is 0.
function cancelAllOrders(
uint cutoff
address owner,
uint cutoff
)
external;

/// @dev Submit a order-ring for validation and settlement.
/// @param addressesList List of each order's owner, signer, tokenS, wallet,
/// @param addressesList List of each order's owner, broker, tokenS, wallet,
/// authAddr, and order interceptor.
/// Note that next order's `tokenS` equals this order's
/// `tokenB`.
Expand All @@ -110,7 +116,7 @@ contract IExchange {
/// validUntil (second), lrcFee, and rateAmountS.
/// @param optionList Options associated with each order.
/// @param sigList Signature lists.
/// @param miner Miner address.
/// @param feeRecipient Mineing fee recipient address.
/// @param inteceptor Ring interceptor address.
/// @param feeSelections -
/// Bits to indicate fee selections. `1` represents margin
Expand All @@ -120,7 +126,7 @@ contract IExchange {
uint[6][] valuesList,
uint8[] optionList,
bytes[] sigList,
address miner,
address feeRecipient,
address inteceptor,
uint8 feeSelections
)
Expand Down
Loading