Skip to content
This repository has been archived by the owner on Sep 20, 2019. It is now read-only.

feature/multi-trade #95

Open
wants to merge 9 commits into
base: version/3.0.0
Choose a base branch
from
69 changes: 67 additions & 2 deletions contracts/Exchange.sol
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,63 @@ contract Exchange is Ownable, ExchangeInterface {
emit Unsubscribed(msg.sender);
}


function multifillUpTo(address makerToken, address takerToken, address[] makers, uint[] values, bytes32[] sigmain, uint16[] sigaux, uint maxFillAmount) external {
require(makers.length == sigaux.length);
require(makers.length*2 == sigmain.length);
require(makers.length*4 == values.length);

address[3] memory addrs;
uint[4] memory vals;
bytes memory s;
uint filledSoFar = 0;

for (uint i = 0; i < makers.length; i++){
for (uint j = 0; j < 4; j++){
vals[j] = values[i*4 + j];
}
addrs[0] = makers[i];
addrs[1] = makerToken;
addrs[2] = takerToken;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no point in addrs

s = sigArrayToBytes(sigmain, sigaux, i);
uint filled = exchange.trade(OrderLibrary.createOrder(addrs, vals), msg.sender, s, maxFillAmount-filledSoFar);
filledSoFar = filledSoFar + filled;
if (filledSoFar >= maxFillAmount){
return;
}
}
}


function multitrade(address[] addresses, uint[] values, bytes32[] sigmain, uint16[] sigaux, uint[] maxFillAmount) external {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if we do not fully use it, we should consider ABI Encoder V2 here, it will allow us to use an array of bytes, rather than this weird split we are doing here.

require(addresses.length == 3*sigaux.length);
require(values.length == 4*sigaux.length);
require(sigmain.length == 2*sigaux.length);
require(maxFillAmount.length == sigaux.length);

address[3] memory addrs;
uint[4] memory vals;
bytes memory s;

for (uint i = 0; i < sigaux.length; i++){
for (uint j = 0; j < 3; j++){
addrs[j] = addresses[(i*3)+j];
}
for (j = 0; j < 4; j++){
vals[j] = values[(i*4)+j];
}
s = sigArrayToBytes(sigmain, sigaux, i);
exchange.trade(OrderLibrary.createOrder(addrs, vals), msg.sender, s, maxFillAmount[i]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for s, do it right here.

}
}

/// @dev Takes an order.
/// @param addresses Array of trade's maker, makerToken and takerToken.
/// @param values Array of trade's makerTokenAmount, takerTokenAmount, expires and nonce.
/// @param signature Signed order along with signature mode.
/// @param maxFillAmount Maximum amount of the order to be filled.
function trade(address[3] addresses, uint[4] values, bytes signature, uint maxFillAmount) external {
exchange.trade(OrderLibrary.createOrder(addresses, values), msg.sender, signature, maxFillAmount);
function trade(address[3] addresses, uint[4] values, bytes signature, uint maxFillAmount) external returns (uint) {
return exchange.trade(OrderLibrary.createOrder(addresses, values), msg.sender, signature, maxFillAmount);
}

/// @dev Cancels an order.
Expand Down Expand Up @@ -169,4 +219,19 @@ contract Exchange is Ownable, ExchangeInterface {
function isOrdered(address user, bytes32 hash) public view returns (bool) {
return exchange.orders[user][hash];
}

function sigArrayToBytes(bytes32[] sm, uint16[] sa, uint i) internal pure returns (bytes) {
bytes32 s1 = sm[i*2];
bytes32 s2 = sm[i*2 + 1];
uint16 s3 = sa[i];
uint8 s4 = uint8(s3 % 256);
s3 = (s3 - uint16(s4)) / 256;
bytes memory s = new bytes(66);
assembly {
mstore(add(s, 32), s1)
mstore(add(s, 64), s2)
mstore8(add(s, 96), s3)
mstore8(add(s, 97), s4)
}
}
}
4 changes: 3 additions & 1 deletion contracts/Libraries/ExchangeLibrary.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ library ExchangeLibrary {
bytes signature,
uint maxFillAmount
)
internal
internal returns (uint)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

returns on new line

{
require(taker != order.maker);
bytes32 hash = order.hash();
Expand Down Expand Up @@ -90,6 +90,8 @@ library ExchangeLibrary {
order.maker,
taker
);

return fillAmount;
}

/// @dev Indicates whether or not an certain amount of an order can be traded.
Expand Down