Skip to content
This repository has been archived by the owner on Jul 9, 2021. It is now read-only.

[WIP] Add SignatureType.OrderValidator support to Exchange #1773

Closed
Closed
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
4 changes: 4 additions & 0 deletions contracts/exchange/CHANGELOG.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
{
"note": "Refactor example contracts that use `executeTransaction`",
"pr": 1753
},
{
"note": "Add support for `SignatureType.OrderValidator` for orders",
"pr": 0
}
]
},
Expand Down
27 changes: 24 additions & 3 deletions contracts/exchange/contracts/examples/Validator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@
*/

pragma solidity ^0.5.5;
pragma experimental ABIEncoderV2;

import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol";
import "../src/interfaces/IValidator.sol";


contract Validator is
contract Validator is
IValidator
{

// The single valid signer for this wallet.
// The single valid signer for this validator.
// solhint-disable-next-line var-name-mixedcase
address internal VALID_SIGNER;

Expand All @@ -35,12 +37,12 @@ contract Validator is
VALID_SIGNER = validSigner;
}

// solhint-disable no-unused-vars
/// @dev Verifies that a signature is valid. `signer` must match `VALID_SIGNER`.
/// @param hash Message hash that is signed.
/// @param signerAddress Address that should have signed the given hash.
/// @param signature Proof of signing.
/// @return Validity of signature.
// solhint-disable no-unused-vars
function isValidSignature(
bytes32 hash,
address signerAddress,
Expand All @@ -53,4 +55,23 @@ contract Validator is
return (signerAddress == VALID_SIGNER);
}
// solhint-enable no-unused-vars

// solhint-disable no-unused-vars
/// @dev Verifies that a signature is valid. `signer` must match `VALID_SIGNER`.
/// @param order The order.
/// @param signerAddress Address that should have signed the given hash.
/// @param signature Proof of signing.
/// @return Validity of signature.
function isValidOrder(
LibOrder.Order calldata order,
address signerAddress,
bytes calldata signature
)
external
view
returns (bool isValid)
{
return (signerAddress == VALID_SIGNER);
}
// solhint-enable no-unused-vars
}
31 changes: 16 additions & 15 deletions contracts/exchange/contracts/src/MixinExchangeCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ contract MixinExchangeCore is
address senderAddress = makerAddress == msg.sender ? address(0) : msg.sender;

// orderEpoch is initialized to 0, so to cancelUpTo we need salt + 1
uint256 newOrderEpoch = targetOrderEpoch + 1;
uint256 newOrderEpoch = targetOrderEpoch + 1;
uint256 oldOrderEpoch = orderEpoch[makerAddress][senderAddress];

// Ensure orderEpoch is monotonically increasing
require(
newOrderEpoch > oldOrderEpoch,
newOrderEpoch > oldOrderEpoch,
"INVALID_NEW_ORDER_EPOCH"
);

Expand Down Expand Up @@ -193,15 +193,15 @@ contract MixinExchangeCore is

// Fetch taker address
address takerAddress = getCurrentContextAddress();

// Assert that the order is fillable by taker
assertFillableOrder(
order,
orderInfo,
takerAddress,
signature
);

// Get amount of takerAsset to fill
uint256 remainingTakerAssetAmount = safeSub(order.takerAssetAmount, orderInfo.orderTakerAssetFilledAmount);
uint256 takerAssetFilledAmount = min256(takerAssetFillAmount, remainingTakerAssetAmount);
Expand All @@ -226,7 +226,7 @@ contract MixinExchangeCore is
orderInfo.orderTakerAssetFilledAmount,
fillResults
);

// Settle order
settleOrder(
order,
Expand Down Expand Up @@ -309,7 +309,7 @@ contract MixinExchangeCore is
order.takerAssetData
);
}

/// @dev Validates context for fillOrder. Succeeds or throws.
/// @param order to be filled.
/// @param orderInfo OrderStatus, orderHash, and amount already filled of order.
Expand All @@ -329,27 +329,28 @@ contract MixinExchangeCore is
orderInfo.orderStatus == uint8(OrderStatus.FILLABLE),
"ORDER_UNFILLABLE"
);

// Validate sender is allowed to fill this order
if (order.senderAddress != address(0)) {
require(
order.senderAddress == msg.sender,
"INVALID_SENDER"
);
}

// Validate taker is allowed to fill this order
if (order.takerAddress != address(0)) {
require(
order.takerAddress == takerAddress,
"INVALID_TAKER"
);
}

// Validate Maker signature (check only if first time seen)
if (orderInfo.orderTakerAssetFilledAmount == 0) {
require(
isValidSignature(
isValidOrderWithHashSignature(
order,
orderInfo.orderHash,
order.makerAddress,
signature
Expand All @@ -358,7 +359,7 @@ contract MixinExchangeCore is
);
}
}

/// @dev Validates context for fillOrder. Succeeds or throws.
/// @param order to be filled.
/// @param orderInfo OrderStatus, orderHash, and amount already filled of order.
Expand All @@ -381,23 +382,23 @@ contract MixinExchangeCore is
takerAssetFillAmount != 0,
"INVALID_TAKER_AMOUNT"
);

// Make sure taker does not pay more than desired amount
// NOTE: This assertion should never fail, it is here
// as an extra defence against potential bugs.
require(
takerAssetFilledAmount <= takerAssetFillAmount,
"TAKER_OVERPAY"
);

// Make sure order is not overfilled
// NOTE: This assertion should never fail, it is here
// as an extra defence against potential bugs.
require(
safeAdd(orderInfo.orderTakerAssetFilledAmount, takerAssetFilledAmount) <= order.takerAssetAmount,
"ORDER_OVERFILL"
);

// Make sure order is filled at acceptable price.
// The order has an implied price from the makers perspective:
// order price = order.makerAssetAmount / order.takerAssetAmount
Expand All @@ -417,7 +418,7 @@ contract MixinExchangeCore is
// as an extra defence against potential bugs.
require(
safeMul(makerAssetFilledAmount, order.takerAssetAmount)
<=
<=
safeMul(order.makerAssetAmount, takerAssetFilledAmount),
"INVALID_FILL_PRICE"
);
Expand Down
Loading