Implement ABIv2 in ExchangeCore

This commit is contained in:
Remco Bloemen
2018-02-26 16:35:52 -08:00
committed by Amir Bandeali
parent 6f3c6f7599
commit c1b8a7fbb7
2 changed files with 33 additions and 60 deletions

View File

@@ -17,6 +17,7 @@
*/
pragma solidity ^0.4.19;
pragma experimental ABIEncoderV2;
import "./mixins/MExchangeCore.sol";
import "./mixins/MSettlement.sol";
@@ -76,37 +77,21 @@ contract MixinExchangeCore is
/// @param signature Proof of signing order by maker.
/// @return Total amount of takerToken filled in trade.
function fillOrder(
address[5] orderAddresses,
uint[6] orderValues,
Order order,
uint takerTokenFillAmount,
bytes signature)
public
returns (uint256 takerTokenFilledAmount)
{
Order memory order = Order({
maker: orderAddresses[0],
taker: orderAddresses[1],
makerToken: orderAddresses[2],
takerToken: orderAddresses[3],
feeRecipient: orderAddresses[4],
makerTokenAmount: orderValues[0],
takerTokenAmount: orderValues[1],
makerFee: orderValues[2],
takerFee: orderValues[3],
expirationTimestampInSec: orderValues[4],
orderHash: getOrderHash(orderAddresses, orderValues)
});
// Compute the order hash
bytes32 orderHash = getOrderHash(order);
// Validate order and maker only if first time seen
// TODO: Read filled and cancelled only once
if (filled[order.orderHash] == 0 && cancelled[order.orderHash] == 0) {
if (filled[orderHash] == 0 && cancelled[orderHash] == 0) {
require(order.makerTokenAmount > 0);
require(order.takerTokenAmount > 0);
require(isValidSignature(
keccak256(orderSchemaHash, order.orderHash),
order.maker,
signature
));
require(isValidSignature(orderHash, order.maker, signature));
}
// Validate taker
@@ -117,26 +102,26 @@ contract MixinExchangeCore is
// Validate order expiration
if (block.timestamp >= order.expirationTimestampInSec) {
LogError(uint8(Errors.ORDER_EXPIRED), order.orderHash);
LogError(uint8(Errors.ORDER_EXPIRED), orderHash);
return 0;
}
// Validate order availability
uint256 remainingTakerTokenAmount = safeSub(order.takerTokenAmount, getUnavailableTakerTokenAmount(order.orderHash));
uint256 remainingTakerTokenAmount = safeSub(order.takerTokenAmount, getUnavailableTakerTokenAmount(orderHash));
takerTokenFilledAmount = min256(takerTokenFillAmount, remainingTakerTokenAmount);
if (takerTokenFilledAmount == 0) {
LogError(uint8(Errors.ORDER_FULLY_FILLED_OR_CANCELLED), order.orderHash);
LogError(uint8(Errors.ORDER_FULLY_FILLED_OR_CANCELLED), orderHash);
return 0;
}
// Validate fill order rounding
if (isRoundingError(takerTokenFilledAmount, order.takerTokenAmount, order.makerTokenAmount)) {
LogError(uint8(Errors.ROUNDING_ERROR_TOO_LARGE), order.orderHash);
LogError(uint8(Errors.ROUNDING_ERROR_TOO_LARGE), orderHash);
return 0;
}
// Update state
filled[order.orderHash] = safeAdd(filled[order.orderHash], takerTokenFilledAmount);
filled[orderHash] = safeAdd(filled[orderHash], takerTokenFilledAmount);
// Settle order
var (makerTokenFilledAmount, makerFeePaid, takerFeePaid) =
@@ -153,7 +138,7 @@ contract MixinExchangeCore is
takerTokenFilledAmount,
makerFeePaid,
takerFeePaid,
order.orderHash
orderHash
);
return takerTokenFilledAmount;
}
@@ -164,45 +149,34 @@ contract MixinExchangeCore is
/// @param takerTokenCancelAmount Desired amount of takerToken to cancel in order.
/// @return Amount of takerToken cancelled.
function cancelOrder(
address[5] orderAddresses,
uint256[6] orderValues,
Order order,
uint256 takerTokenCancelAmount)
public
returns (uint256 takerTokenCancelledAmount)
{
Order memory order = Order({
maker: orderAddresses[0],
taker: orderAddresses[1],
makerToken: orderAddresses[2],
takerToken: orderAddresses[3],
feeRecipient: orderAddresses[4],
makerTokenAmount: orderValues[0],
takerTokenAmount: orderValues[1],
makerFee: orderValues[2],
takerFee: orderValues[3],
expirationTimestampInSec: orderValues[4],
orderHash: getOrderHash(orderAddresses, orderValues)
});
// Compute the order hash
bytes32 orderHash = getOrderHash(order);
// Validate the order
require(order.makerTokenAmount > 0);
require(order.takerTokenAmount > 0);
require(takerTokenCancelAmount > 0);
require(order.maker == msg.sender);
if (block.timestamp >= order.expirationTimestampInSec) {
LogError(uint8(Errors.ORDER_EXPIRED), order.orderHash);
LogError(uint8(Errors.ORDER_EXPIRED), orderHash);
return 0;
}
uint256 remainingTakerTokenAmount = safeSub(order.takerTokenAmount, getUnavailableTakerTokenAmount(order.orderHash));
uint256 remainingTakerTokenAmount = safeSub(order.takerTokenAmount, getUnavailableTakerTokenAmount(orderHash));
takerTokenCancelledAmount = min256(takerTokenCancelAmount, remainingTakerTokenAmount);
if (takerTokenCancelledAmount == 0) {
LogError(uint8(Errors.ORDER_FULLY_FILLED_OR_CANCELLED), order.orderHash);
LogError(uint8(Errors.ORDER_FULLY_FILLED_OR_CANCELLED), orderHash);
return 0;
}
cancelled[order.orderHash] = safeAdd(cancelled[order.orderHash], takerTokenCancelledAmount);
cancelled[orderHash] = safeAdd(cancelled[orderHash], takerTokenCancelledAmount);
LogCancel(
order.maker,
order.feeRecipient,
@@ -210,7 +184,7 @@ contract MixinExchangeCore is
order.takerToken,
getPartialAmount(takerTokenCancelledAmount, order.takerTokenAmount, order.makerTokenAmount),
takerTokenCancelledAmount,
order.orderHash
orderHash
);
return takerTokenCancelledAmount;
}

View File

@@ -17,20 +17,19 @@
*/
pragma solidity ^0.4.19;
pragma experimental ABIEncoderV2;
contract MExchangeCore {
function fillOrder(
address[5] orderAddresses,
uint256[6] orderValues,
uint256 takerTokenFillAmount,
bytes signature)
public
returns (uint256 takerTokenFilledAmount);
Order order,
uint256 takerTokenFillAmount,
bytes signature)
public
returns (uint256 takerTokenFilledAmount);
function cancelOrder(
address[5] orderAddresses,
uint256[6] orderValues,
Order order,
uint256 takerTokenCancelAmount)
public
returns (uint256 takerTokenCancelledAmount);