Split up mixins and interfaces

This commit is contained in:
Amir Bandeali
2018-05-04 17:00:39 -07:00
parent bbf088d903
commit 395d060427
29 changed files with 507 additions and 744 deletions

View File

@@ -19,9 +19,9 @@
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
import "../../../utils/LibBytes/LibBytes.sol";
import "../../../tokens/ERC20Token/IERC20Token.sol";
import "../MixinAssetProxy.sol";
import "../../utils/LibBytes/LibBytes.sol";
import "../../tokens/ERC20Token/IERC20Token.sol";
import "./MixinAssetProxy.sol";
contract ERC20Proxy is
LibBytes,

View File

@@ -19,9 +19,9 @@
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
import "../../../utils/LibBytes/LibBytes.sol";
import "../../../tokens/ERC721Token/ERC721Token.sol";
import "../MixinAssetProxy.sol";
import "../../utils/LibBytes/LibBytes.sol";
import "../../tokens/ERC721Token/ERC721Token.sol";
import "./MixinAssetProxy.sol";
contract ERC721Proxy is
LibBytes,

View File

@@ -20,11 +20,9 @@ pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
import "./mixins/MAssetProxy.sol";
import "./IAssetProxy.sol";
import "../../utils/Authorizable/Authorizable.sol";
contract MixinAssetProxy is
IAssetProxy,
Authorizable,
MAssetProxy
{

View File

@@ -19,7 +19,7 @@
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
import "../../utils/Authorizable/IAuthorizable.sol";
import "../../../utils/Authorizable/IAuthorizable.sol";
contract IAssetProxy is
IAuthorizable

View File

@@ -19,7 +19,11 @@
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
contract MAssetProxy {
import "../interfaces/IAssetProxy.sol";
contract MAssetProxy is
IAssetProxy
{
/// @dev Internal version of `transferFrom`.
/// @param assetMetadata Encoded byte array.

View File

@@ -1,289 +0,0 @@
/*
Copyright 2018 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.4.21;
pragma experimental ABIEncoderV2;
contract IExchange {
// Error Codes
enum Errors {
ORDER_EXPIRED, // Order has already expired
ORDER_FULLY_FILLED_OR_CANCELLED, // Order has already been fully filled or cancelled
ROUNDING_ERROR_TOO_LARGE, // Rounding error too large
INSUFFICIENT_BALANCE_OR_ALLOWANCE // Insufficient balance or allowance for token transfer
}
event LogError(uint8 indexed errorId, bytes32 indexed orderHash);
event LogFill(
address indexed maker,
address taker,
address indexed feeRecipient,
bytes makerAssetData,
bytes takerAssetData,
uint256 makerAssetFilledAmount,
uint256 takerAssetFilledAmount,
uint256 makerFeePaid,
uint256 takerFeePaid,
bytes32 indexed orderHash
);
event LogCancel(
address indexed maker,
address indexed feeRecipient,
bytes makerAssetData,
bytes takerAssetData,
uint256 makerAssetCancelledAmount,
uint256 takerAssetCancelledAmount,
bytes32 indexed orderHash
);
function ZRX_TOKEN_CONTRACT()
public view
returns (address);
function EXTERNAL_QUERY_GAS_LIMIT()
public view
returns (uint16);
function VERSION()
public view
returns (string);
function filled(bytes32)
public view
returns (uint256);
function cancelled(bytes32)
public view
returns (uint256);
/// @dev Calculates the sum of values already filled and cancelled for a given order.
/// @param orderHash The Keccak-256 hash of the given order.
/// @return Sum of values already filled and cancelled.
function getUnavailableTakerAssetAmount(bytes32 orderHash)
public view
returns (uint256 unavailableTakerAssetAmount);
/// @dev Calculates partial value given a numerator and denominator.
/// @param numerator Numerator.
/// @param denominator Denominator.
/// @param target Value to calculate partial of.
/// @return Partial value of target.
function getPartialAmount(uint256 numerator, uint256 denominator, uint256 target)
public pure
returns (uint256 partialAmount);
/// @dev Checks if rounding error > 0.1%.
/// @param numerator Numerator.
/// @param denominator Denominator.
/// @param target Value to multiply with numerator/denominator.
/// @return Rounding error is present.
function isRoundingError(uint256 numerator, uint256 denominator, uint256 target)
public pure
returns (bool isError);
/// @dev Calculates Keccak-256 hash of order with specified parameters.
/// @param orderAddresses Array of order's maker, taker, makerAsset, takerAsset, and feeRecipient.
/// @param orderValues Array of order's makerAssetAmount, takerAssetAmount, makerFee, takerFee, expirationTimestampInSec, and salt.
/// @return Keccak-256 hash of order.
function getOrderHash(address[5] orderAddresses, uint256[6] orderValues)
public view
returns (bytes32 orderHash);
/// @dev Verifies that an order signature is valid.
/// @param signer address of signer.
/// @param hash Signed Keccak-256 hash.
/// @param v ECDSA signature parameter v.
/// @param r ECDSA signature parameters r.
/// @param s ECDSA signature parameters s.
/// @return Validity of order signature.
function isValidSignature(
address signer,
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s)
public pure
returns (bool isValid);
/// @dev Fills the input order.
/// @param orderAddresses Array of order's maker, taker, makerAsset, takerAsset, and feeRecipient.
/// @param orderValues Array of order's makerAssetAmount, takerAssetAmount, makerFee, takerFee, expirationTimestampInSec, and salt.
/// @param takerAssetFillAmount Desired amount of takerAsset to fill.
/// @param v ECDSA signature parameter v.
/// @param r ECDSA signature parameters r.
/// @param s ECDSA signature parameters s.
/// @return Total amount of takerAsset filled in trade.
function fillOrder(
address[5] orderAddresses,
uint256[6] orderValues,
uint256 takerAssetFillAmount,
uint8 v,
bytes32 r,
bytes32 s)
public
returns (uint256 takerAssetFilledAmount);
/// @dev Cancels the input order.
/// @param orderAddresses Array of order's maker, taker, makerAsset, takerAsset, and feeRecipient.
/// @param orderValues Array of order's makerAssetAmount, takerAssetAmount, makerFee, takerFee, expirationTimestampInSec, and salt.
/// @param takerAssetCancelAmount Desired amount of takerAsset to cancel in order.
/// @return Amount of takerAsset cancelled.
function cancelOrder(
address[5] orderAddresses,
uint256[6] orderValues,
uint256 takerAssetCancelAmount)
public
returns (uint256 takerAssetCancelledAmount);
/// @dev Cancels all orders for a specified maker up to a certain time.
/// @param salt Orders created with a salt less or equal to this value will be cancelled.
function cancelOrdersUpTo(uint256 salt)
external;
/// @dev Fills an order with specified parameters and ECDSA signature. Throws if specified amount not filled entirely.
/// @param orderAddresses Array of order's maker, taker, makerAsset, takerAsset, and feeRecipient.
/// @param orderValues Array of order's makerAssetAmount, takerAssetAmount, makerFee, takerFee, expirationTimestampInSec, and salt.
/// @param takerAssetFillAmount Desired amount of takerAsset to fill.
/// @param v ECDSA signature parameter v.
/// @param r ECDSA signature parameters r.
/// @param s ECDSA signature parameters s.
function fillOrKillOrder(
address[5] orderAddresses,
uint256[6] orderValues,
uint256 takerAssetFillAmount,
uint8 v,
bytes32 r,
bytes32 s)
public;
/// @dev Fills an order with specified parameters and ECDSA signature. Returns false if the transaction would otherwise revert.
/// @param orderAddresses Array of order's maker, taker, makerAsset, takerAsset, and feeRecipient.
/// @param orderValues Array of order's makerAssetAmount, takerAssetAmount, makerFee, takerFee, expirationTimestampInSec, and salt.
/// @param takerAssetFillAmount Desired amount of takerAsset to fill.
/// @param v ECDSA signature parameter v.
/// @param r ECDSA signature parameters r.
/// @param s ECDSA signature parameters s.
/// @return Success if the transaction did not revert.
/// @return Total amount of takerAsset filled in trade.
function fillOrderNoThrow(
address[5] orderAddresses,
uint256[6] orderValues,
uint256 takerAssetFillAmount,
uint8 v,
bytes32 r,
bytes32 s)
public
returns (bool success, uint256 takerAssetFilledAmount);
/// @dev Synchronously executes multiple calls of fillOrder in a single transaction.
/// @param orderAddresses Array of address arrays containing individual order addresses.
/// @param orderValues Array of uint256 arrays containing individual order values.
/// @param takerAssetFillAmounts Array of desired amounts of takerAsset to fill in orders.
/// @param v Array ECDSA signature v parameters.
/// @param r Array of ECDSA signature r parameters.
/// @param s Array of ECDSA signature s parameters.
function batchFillOrders(
address[5][] orderAddresses,
uint256[6][] orderValues,
uint256[] takerAssetFillAmounts,
uint8[] v,
bytes32[] r,
bytes32[] s)
external;
/// @dev Synchronously executes multiple calls of fillOrKill in a single transaction.
/// @param orderAddresses Array of address arrays containing individual order addresses.
/// @param orderValues Array of uint256 arrays containing individual order values.
/// @param takerAssetFillAmounts Array of desired amounts of takerAsset to fill in orders.
/// @param v Array ECDSA signature v parameters.
/// @param r Array of ECDSA signature r parameters.
/// @param s Array of ECDSA signature s parameters.
function batchFillOrKillOrders(
address[5][] orderAddresses,
uint256[6][] orderValues,
uint256[] takerAssetFillAmounts,
uint8[] v,
bytes32[] r,
bytes32[] s)
external;
/// @dev Synchronously executes multiple calls of fillOrderNoThrow in a single transaction.
/// @param orderAddresses Array of address arrays containing individual order addresses.
/// @param orderValues Array of uint256 arrays containing individual order values.
/// @param takerAssetFillAmounts Array of desired amounts of takerAsset to fill in orders.
/// @param v Array ECDSA signature v parameters.
/// @param r Array of ECDSA signature r parameters.
/// @param s Array of ECDSA signature s parameters.
function batchFillOrdersNoThrow(
address[5][] orderAddresses,
uint256[6][] orderValues,
uint256[] takerAssetFillAmounts,
uint8[] v,
bytes32[] r,
bytes32[] s)
external;
/// @dev Synchronously executes multiple fill orders in a single transaction until total takerAssetFillAmount filled.
/// @param orderAddresses Array of address arrays containing individual order addresses.
/// @param orderValues Array of uint256 arrays containing individual order values.
/// @param takerAssetFillAmount Desired total amount of takerAsset to fill in orders.
/// @param v Array ECDSA signature v parameters.
/// @param r Array of ECDSA signature r parameters.
/// @param s Array of ECDSA signature s parameters.
/// @return Total amount of takerAssetFillAmount filled in orders.
function marketFillOrders(
address[5][] orderAddresses,
uint256[6][] orderValues,
uint256 takerAssetFillAmount,
uint8[] v,
bytes32[] r,
bytes32[] s)
external
returns (uint256 totalTakerAssetFilledAmount);
/// @dev Synchronously executes multiple calls of fillOrderNoThrow in a single transaction until total takerAssetFillAmount filled.
/// @param orderAddresses Array of address arrays containing individual order addresses.
/// @param orderValues Array of uint256 arrays containing individual order values.
/// @param takerAssetFillAmount Desired total amount of takerAsset to fill in orders.
/// @param v Array ECDSA signature v parameters.
/// @param r Array of ECDSA signature r parameters.
/// @param s Array of ECDSA signature s parameters.
/// @return Total amount of takerAssetFillAmount filled in orders.
function marketFillOrdersNoThrow(
address[5][] orderAddresses,
uint256[6][] orderValues,
uint256 takerAssetFillAmount,
uint8[] v,
bytes32[] r,
bytes32[] s)
external
returns (uint256 totalTakerAssetFilledAmount);
/// @dev Synchronously cancels multiple orders in a single transaction.
/// @param orderAddresses Array of address arrays containing individual order addresses.
/// @param orderValues Array of uint256 arrays containing individual order values.
/// @param takerAssetCancelAmounts Array of desired amounts of takerAsset to cancel in orders.
function batchCancelOrders(
address[5][] orderAddresses,
uint256[6][] orderValues,
uint256[] takerAssetCancelAmounts)
external;
}

View File

@@ -1,59 +0,0 @@
/*
Copyright 2018 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
contract LibExchangeErrors {
// Error Codes
enum Errors {
ORDER_EXPIRED, // Order has already expired
ORDER_FULLY_FILLED, // Order has already been fully filled
ORDER_CANCELLED, // Order has already been cancelled
ROUNDING_ERROR_TOO_LARGE, // Rounding error too large
INSUFFICIENT_BALANCE_OR_ALLOWANCE // Insufficient balance or allowance for token transfer
}
event ExchangeError(uint8 indexed errorId, bytes32 indexed orderHash);
// Core revert reasons
string constant GREATER_THAN_ZERO_AMOUNT_REQUIRED = "Amount must be greater than 0.";
string constant SIGNATURE_VALIDATION_FAILED = "Signature validation failed.";
string constant INVALID_SENDER = "Invalid `msg.sender`.";
string constant INVALID_CONTEXT = "Function called in an invalid context.";
string constant INVALID_NEW_MAKER_EPOCH = "Specified salt must be greater than or equal to existing makerEpoch.";
// Transaction revert reasons
string constant DUPLICATE_TRANSACTION_HASH = "Transaction has already been executed.";
string constant TRANSACTION_EXECUTION_FAILED = "Transaction execution failed.";
// Wrapper revert reasons
string constant COMPLETE_FILL_FAILED = "Desired fill amount could not be completely filled.";
string constant ASSET_DATA_MISMATCH = "Asset data must be the same for each order.";
// Asset proxy dispatcher revert reasons
string constant GREATER_THAN_ZERO_LENGTH_REQUIRED = "Length must be greater than 0.";
string constant OLD_ASSET_PROXY_MISMATCH = "Old asset proxy does not match asset proxy at given id.";
string constant NEW_ASSET_PROXY_MISMATCH = "New asset proxy id does not match given id.";
// Signature validator revert reasons
string constant INVALID_SIGNATURE_LENGTH = "Invalid signature length.";
string constant ILLEGAL_SIGNATURE_TYPE = "Illegal signature type.";
string constant UNSUPPORTED_SIGNATURE_TYPE = "Unsupported signature type.";
}

View File

@@ -1,48 +0,0 @@
/*
Copyright 2018 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
import "../../utils/SafeMath/SafeMath.sol";
contract LibFillResults is
SafeMath
{
struct FillResults {
uint256 makerAssetFilledAmount;
uint256 takerAssetFilledAmount;
uint256 makerFeePaid;
uint256 takerFeePaid;
}
/// @dev Adds properties of both FillResults instances.
/// Modifies the first FillResults instance specified.
/// @param totalFillResults Fill results instance that will be added onto.
/// @param singleFillResults Fill results instance that will be added to totalFillResults.
function addFillResults(FillResults memory totalFillResults, FillResults memory singleFillResults)
internal
pure
{
totalFillResults.makerAssetFilledAmount = safeAdd(totalFillResults.makerAssetFilledAmount, singleFillResults.makerAssetFilledAmount);
totalFillResults.takerAssetFilledAmount = safeAdd(totalFillResults.takerAssetFilledAmount, singleFillResults.takerAssetFilledAmount);
totalFillResults.makerFeePaid = safeAdd(totalFillResults.makerFeePaid, singleFillResults.makerFeePaid);
totalFillResults.takerFeePaid = safeAdd(totalFillResults.takerFeePaid, singleFillResults.takerFeePaid);
}
}

View File

@@ -1,73 +0,0 @@
/*
Copyright 2018 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
import "../../utils/SafeMath/SafeMath.sol";
contract LibMath is
SafeMath
{
/// @dev Calculates partial value given a numerator and denominator.
/// @param numerator Numerator.
/// @param denominator Denominator.
/// @param target Value to calculate partial of.
/// @return Partial value of target.
function getPartialAmount(
uint256 numerator,
uint256 denominator,
uint256 target)
internal
pure
returns (uint256 partialAmount)
{
partialAmount = safeDiv(
safeMul(numerator, target),
denominator
);
return partialAmount;
}
/// @dev Checks if rounding error > 0.1%.
/// @param numerator Numerator.
/// @param denominator Denominator.
/// @param target Value to multiply with numerator/denominator.
/// @return Rounding error is present.
function isRoundingError(
uint256 numerator,
uint256 denominator,
uint256 target)
internal
pure
returns (bool isError)
{
uint256 remainder = mulmod(target, numerator, denominator);
if (remainder == 0) {
return false; // No rounding error.
}
uint256 errPercentageTimes1000000 = safeDiv(
safeMul(remainder, 1000000),
safeMul(numerator, target)
);
isError = errPercentageTimes1000000 > 1000;
return isError;
}
}

View File

@@ -1,85 +0,0 @@
/*
Copyright 2018 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
contract LibOrder {
bytes32 constant ORDER_SCHEMA_HASH = keccak256(
"address exchangeAddress",
"address makerAddress",
"address takerAddress",
"address feeRecipientAddress",
"address senderAddress",
"uint256 makerAssetAmount",
"uint256 takerAssetAmount",
"uint256 makerFee",
"uint256 takerFee",
"uint256 expirationTimeSeconds",
"uint256 salt",
"bytes makerAssetData",
"bytes takerAssetData"
);
struct Order {
address makerAddress;
address takerAddress;
address feeRecipientAddress;
address senderAddress;
uint256 makerAssetAmount;
uint256 takerAssetAmount;
uint256 makerFee;
uint256 takerFee;
uint256 expirationTimeSeconds;
uint256 salt;
bytes makerAssetData;
bytes takerAssetData;
}
/// @dev Calculates Keccak-256 hash of the order.
/// @param order The order structure.
/// @return Keccak-256 EIP712 hash of the order.
function getOrderHash(Order memory order)
internal
view
returns (bytes32 orderHash)
{
// TODO: EIP712 is not finalized yet
// Source: https://github.com/ethereum/EIPs/pull/712
orderHash = keccak256(
ORDER_SCHEMA_HASH,
keccak256(
address(this),
order.makerAddress,
order.takerAddress,
order.feeRecipientAddress,
order.senderAddress,
order.makerAssetAmount,
order.takerAssetAmount,
order.makerFee,
order.takerFee,
order.expirationTimeSeconds,
order.salt,
order.makerAssetData,
order.takerAssetData
)
);
return orderHash;
}
}

View File

@@ -17,11 +17,10 @@
*/
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
import "../../utils/Ownable/Ownable.sol";
import "../AssetProxy/IAssetProxy.sol";
import "./LibExchangeErrors.sol";
import "../AssetProxy/interfaces/IAssetProxy.sol";
import "./lib/LibExchangeErrors.sol";
import "./mixins/MAssetProxyDispatcher.sol";
contract MixinAssetProxyDispatcher is
@@ -32,33 +31,6 @@ contract MixinAssetProxyDispatcher is
// Mapping from Asset Proxy Id's to their respective Asset Proxy
mapping (uint8 => IAssetProxy) public assetProxies;
/// @dev Forwards arguments to assetProxy and calls `transferFrom`. Either succeeds or throws.
/// @param assetMetadata Byte array encoded for the respective asset proxy.
/// @param from Address to transfer token from.
/// @param to Address to transfer token to.
/// @param amount Amount of token to transfer.
function dispatchTransferFrom(
bytes memory assetMetadata,
address from,
address to,
uint256 amount)
internal
{
// Do nothing if no amount should be transferred.
if (amount > 0) {
// Lookup asset proxy
require(
assetMetadata.length >= 1,
GREATER_THAN_ZERO_LENGTH_REQUIRED
);
uint8 assetProxyId = uint8(assetMetadata[0]);
IAssetProxy assetProxy = assetProxies[assetProxyId];
// transferFrom will either succeed or throw.
assetProxy.transferFrom(assetMetadata, from, to, amount);
}
}
/// @dev Registers an asset proxy to an asset proxy id.
/// An id can only be assigned to a single proxy at a given time.
/// @param assetProxyId Id to register`newAssetProxy` under.
@@ -104,4 +76,31 @@ contract MixinAssetProxyDispatcher is
address assetProxy = address(assetProxies[assetProxyId]);
return assetProxy;
}
/// @dev Forwards arguments to assetProxy and calls `transferFrom`. Either succeeds or throws.
/// @param assetMetadata Byte array encoded for the respective asset proxy.
/// @param from Address to transfer token from.
/// @param to Address to transfer token to.
/// @param amount Amount of token to transfer.
function dispatchTransferFrom(
bytes memory assetMetadata,
address from,
address to,
uint256 amount)
internal
{
// Do nothing if no amount should be transferred.
if (amount > 0) {
// Lookup asset proxy
require(
assetMetadata.length >= 1,
GREATER_THAN_ZERO_LENGTH_REQUIRED
);
uint8 assetProxyId = uint8(assetMetadata[0]);
IAssetProxy assetProxy = assetProxies[assetProxyId];
// transferFrom will either succeed or throw.
assetProxy.transferFrom(assetMetadata, from, to, amount);
}
}
}

View File

@@ -19,18 +19,15 @@
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
import "./LibFillResults.sol";
import "./LibOrder.sol";
import "./LibMath.sol";
import "./LibExchangeErrors.sol";
import "./lib/LibFillResults.sol";
import "./lib/LibOrder.sol";
import "./lib/LibMath.sol";
import "./lib/LibExchangeErrors.sol";
import "./mixins/MExchangeCore.sol";
import "./mixins/MSettlement.sol";
import "./mixins/MSignatureValidator.sol";
import "./mixins/MTransactions.sol";
/// @dev Provides MExchangeCore
/// @dev Consumes MSettlement
/// @dev Consumes MSignatureValidator
contract MixinExchangeCore is
LibOrder,
LibFillResults,
@@ -51,35 +48,19 @@ contract MixinExchangeCore is
// Orders with a salt less than their maker's epoch are considered cancelled
mapping (address => uint256) public makerEpoch;
event Fill(
address indexed makerAddress,
address takerAddress,
address indexed feeRecipientAddress,
uint256 makerAssetFilledAmount,
uint256 takerAssetFilledAmount,
uint256 makerFeePaid,
uint256 takerFeePaid,
bytes32 indexed orderHash,
bytes makerAssetData,
bytes takerAssetData
);
event Cancel(
address indexed makerAddress,
address indexed feeRecipientAddress,
bytes32 indexed orderHash,
bytes makerAssetData,
bytes takerAssetData
);
event CancelUpTo(
address indexed makerAddress,
uint256 makerEpoch
);
/*
* Core exchange functions
*/
/// @dev Cancels all orders reated by sender with a salt less than or equal to the specified salt value.
/// @param salt Orders created with a salt less or equal to this value will be cancelled.
function cancelOrdersUpTo(uint256 salt)
external
{
uint256 newMakerEpoch = salt + 1; // makerEpoch is initialized to 0, so to cancelUpTo we need salt + 1
require(
newMakerEpoch > makerEpoch[msg.sender], // epoch must be monotonically increasing
INVALID_NEW_MAKER_EPOCH
);
makerEpoch[msg.sender] = newMakerEpoch;
emit CancelUpTo(msg.sender, newMakerEpoch);
}
/// @dev Fills the input order.
/// @param order Order struct containing order specifications.
@@ -237,19 +218,6 @@ contract MixinExchangeCore is
return true;
}
/// @param salt Orders created with a salt less or equal to this value will be cancelled.
function cancelOrdersUpTo(uint256 salt)
external
{
uint256 newMakerEpoch = salt + 1; // makerEpoch is initialized to 0, so to cancelUpTo we need salt + 1
require(
newMakerEpoch > makerEpoch[msg.sender], // epoch must be monotonically increasing
INVALID_NEW_MAKER_EPOCH
);
makerEpoch[msg.sender] = newMakerEpoch;
emit CancelUpTo(msg.sender, newMakerEpoch);
}
/// @dev Logs a Fill event with the given arguments.
/// The sole purpose of this function is to get around the stack variable limit.
function emitFillEvent(

View File

@@ -17,22 +17,21 @@
*/
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
import "./mixins/MSettlement.sol";
import "./mixins/MAssetProxyDispatcher.sol";
import "./LibOrder.sol";
import "./LibMath.sol";
import "../AssetProxy/IAssetProxy.sol";
import "./lib/LibOrder.sol";
import "./lib/LibMath.sol";
/// @dev Provides MixinSettlement
contract MixinSettlement is
LibMath,
MSettlement,
MAssetProxyDispatcher
{
/// ZRX metadata used for fee transfers.
bytes internal ZRX_PROXY_DATA;
/// @dev Gets the ZRX metadata used for fee transfers.
function zrxProxyData()
external
view
@@ -41,12 +40,20 @@ contract MixinSettlement is
return ZRX_PROXY_DATA;
}
/// TODO: _zrxProxyData should be a constant in production.
/// @dev Constructor sets the metadata that will be used for paying ZRX fees.
/// @param _zrxProxyData Byte array containing ERC20 proxy id concatenated with address of ZRX.
constructor (bytes memory _zrxProxyData)
public
{
ZRX_PROXY_DATA = _zrxProxyData;
}
/// @dev Settles an order by transfering assets between counterparties.
/// @param order Order struct containing order specifications.
/// @param takerAddress Address selling takerAsset and buying makerAsset.
/// @param takerAssetFilledAmount The amount of takerAsset that will be transfered to the order's maker.
/// @return Amount filled by maker and fees paid by maker/taker.
function settleOrder(
LibOrder.Order memory order,
address takerAddress,

View File

@@ -17,33 +17,38 @@
*/
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
import "./mixins/MSignatureValidator.sol";
import "./ISigner.sol";
import "./LibExchangeErrors.sol";
import "./interfaces/ISigner.sol";
import "./lib/LibExchangeErrors.sol";
import "../../utils/LibBytes/LibBytes.sol";
/// @dev Provides MSignatureValidator
contract MixinSignatureValidator is
LibBytes,
LibExchangeErrors,
MSignatureValidator
{
enum SignatureType {
Illegal, // Default value
Invalid,
Caller,
Ecrecover,
EIP712,
Trezor,
Contract,
PreSigned
}
// Mapping of hash => signer => signed
mapping(bytes32 => mapping(address => bool)) preSigned;
/// @dev Approves a hash on-chain using any valid signature type.
/// After presigning a hash, the preSign signature type will become valid for that hash and signer.
/// @param signer Address that should have signed the given hash.
/// @param signature Proof that the hash has been signed by signer.
function preSign(
bytes32 hash,
address signer,
bytes signature)
external
{
require(
isValidSignature(hash, signer, signature),
SIGNATURE_VALIDATION_FAILED
);
preSigned[hash][signer] = true;
}
/// @dev Verifies that a hash has been signed by the given signer.
/// @param hash Any 32 byte hash.
/// @param signer Address that should have signed the given hash.
@@ -183,21 +188,4 @@ contract MixinSignatureValidator is
// NOTE: Reason cannot be assigned to a variable because of https://github.com/ethereum/solidity/issues/4051
revert("Unsupported signature type.");
}
/// @dev Approves a hash on-chain using any valid signature type.
/// After presigning a hash, the preSign signature type will become valid for that hash and signer.
/// @param signer Address that should have signed the given hash.
/// @param signature Proof that the hash has been signed by signer.
function preSign(
bytes32 hash,
address signer,
bytes signature)
external
{
require(
isValidSignature(hash, signer, signature),
SIGNATURE_VALIDATION_FAILED
);
preSigned[hash][signer] = true;
}
}

View File

@@ -16,11 +16,10 @@
*/
pragma solidity ^0.4.21;
pragma experimental ABIEncoderV2;
import "./mixins/MSignatureValidator.sol";
import "./mixins/MTransactions.sol";
import "./LibExchangeErrors.sol";
import "./lib/LibExchangeErrors.sol";
contract MixinTransactions is
LibExchangeErrors,

View File

@@ -21,12 +21,11 @@ pragma experimental ABIEncoderV2;
import "../../utils/LibBytes/LibBytes.sol";
import "./mixins/MExchangeCore.sol";
import "./LibMath.sol";
import "./LibOrder.sol";
import "./LibFillResults.sol";
import "./LibExchangeErrors.sol";
import "./lib/LibMath.sol";
import "./lib/LibOrder.sol";
import "./lib/LibFillResults.sol";
import "./lib/LibExchangeErrors.sol";
/// @dev Consumes MExchangeCore
contract MixinWrapperFunctions is
LibOrder,
LibFillResults,

View File

@@ -0,0 +1,41 @@
/*
Copyright 2018 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.4.23;
contract IAssetProxyDispatcher {
/// @dev Registers an asset proxy to an asset proxy id.
/// An id can only be assigned to a single proxy at a given time.
/// @param assetProxyId Id to register`newAssetProxy` under.
/// @param newAssetProxy Address of new asset proxy to register, or 0x0 to unset assetProxyId.
/// @param oldAssetProxy Existing asset proxy to overwrite, or 0x0 if assetProxyId is currently unused.
function registerAssetProxy(
uint8 assetProxyId,
address newAssetProxy,
address oldAssetProxy)
external;
/// @dev Gets an asset proxy.
/// @param assetProxyId Id of the asset proxy.
/// @return The asset proxy registered to assetProxyId. Returns 0x0 if no proxy is registered.
function getAssetProxy(uint8 assetProxyId)
external
view
returns (address);
}

View File

@@ -0,0 +1,34 @@
/*
Copyright 2018 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
import "./IExchangeCore.sol";
import "./ISignatureValidator.sol";
import "./IAssetProxyDispatcher.sol";
import "./ITransactions.sol";
import "./IWrapperFunctions.sol";
contract IExchange is
IWrapperFunctions,
IExchangeCore,
ISignatureValidator,
ITransactions,
IAssetProxyDispatcher
{}

View File

@@ -0,0 +1,51 @@
/*
Copyright 2018 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
import "../lib/LibOrder.sol";
import "../lib/LibFillResults.sol";
contract IExchangeCore {
/// @dev Cancels all orders reated by sender with a salt less than or equal to the specified salt value.
/// @param salt Orders created with a salt less or equal to this value will be cancelled.
function cancelOrdersUpTo(uint256 salt)
external;
/// @dev Fills the input order.
/// @param order Order struct containing order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell.
/// @param signature Proof that order has been created by maker.
/// @return Amounts filled and fees paid by maker and taker.
function fillOrder(
LibOrder.Order memory order,
uint256 takerAssetFillAmount,
bytes memory signature)
public
returns (LibFillResults.FillResults memory fillResults);
/// @dev After calling, the order can not be filled anymore.
/// @param order Order struct containing order specifications.
/// @return True if the order state changed to cancelled.
/// False if the transaction was already cancelled or expired.
function cancelOrder(LibOrder.Order memory order)
public
returns (bool);
}

View File

@@ -0,0 +1,32 @@
/*
Copyright 2018 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.4.23;
contract ISignatureValidator {
/// @dev Approves a hash on-chain using any valid signature type.
/// After presigning a hash, the preSign signature type will become valid for that hash and signer.
/// @param signer Address that should have signed the given hash.
/// @param signature Proof that the hash has been signed by signer.
function preSign(
bytes32 hash,
address signer,
bytes signature)
external;
}

View File

@@ -17,10 +17,13 @@
*/
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
contract ISigner {
/// @dev Verifies that a signature is valid.
/// @param hash Message hash that is signed.
/// @param signature Proof of signing.
/// @return Validity of order signature.
function isValidSignature(
bytes32 hash,
bytes signature)

View File

@@ -0,0 +1,33 @@
/*
Copyright 2018 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.4.23;
contract ITransactions {
/// @dev Executes an exchange method call in the context of signer.
/// @param salt Arbitrary number to ensure uniqueness of transaction hash.
/// @param signer Address of transaction signer.
/// @param data AbiV2 encoded calldata.
/// @param signature Proof of signer transaction by signer.
function executeTransaction(
uint256 salt,
address signer,
bytes data,
bytes signature)
external;
}

View File

@@ -0,0 +1,142 @@
/*
Copyright 2018 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
import "./lib/LibOrder.sol";
import "./lib/LibFillResults.sol";
contract IWrapperFunctions is
LibOrder,
LibFillResults,
LibMath,
LibBytes,
LibExchangeErrors,
MExchangeCore
{
/// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled.
/// @param order LibOrder.Order struct containing order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell.
/// @param signature Proof that order has been created by maker.
function fillOrKillOrder(
LibOrder.LibOrder.Order memory order,
uint256 takerAssetFillAmount,
bytes memory signature)
public
returns (LibFillResults.LibFillResults.FillResults memory fillResults);
/// @dev Fills an order with specified parameters and ECDSA signature.
/// Returns false if the transaction would otherwise revert.
/// @param order LibOrder.Order struct containing order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell.
/// @param signature Proof that order has been created by maker.
/// @return Amounts filled and fees paid by maker and taker.
function fillOrderNoThrow(
LibOrder.Order memory order,
uint256 takerAssetFillAmount,
bytes memory signature)
public
returns (LibFillResults.FillResults memory fillResults);
/// @dev Synchronously executes multiple calls of fillOrder.
/// @param orders Array of order specifications.
/// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.
/// @param signatures Proofs that orders have been created by makers.
function batchFillOrders(
LibOrder.Order[] memory orders,
uint256[] memory takerAssetFillAmounts,
bytes[] memory signatures)
public;
/// @dev Synchronously executes multiple calls of fillOrKill.
/// @param orders Array of order specifications.
/// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.
/// @param signatures Proofs that orders have been created by makers.
function batchFillOrKillOrders(
LibOrder.Order[] memory orders,
uint256[] memory takerAssetFillAmounts,
bytes[] memory signatures)
public;
/// @dev Fills an order with specified parameters and ECDSA signature.
/// Returns false if the transaction would otherwise revert.
/// @param orders Array of order specifications.
/// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.
/// @param signatures Proofs that orders have been created by makers.
function batchFillOrdersNoThrow(
LibOrder.Order[] memory orders,
uint256[] memory takerAssetFillAmounts,
bytes[] memory signatures)
public;
/// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.
/// @param orders Array of order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell.
/// @param signatures Proofs that orders have been created by makers.
/// @return Amounts filled and fees paid by makers and taker.
function marketSellOrders(
LibOrder.Order[] memory orders,
uint256 takerAssetFillAmount,
bytes[] memory signatures)
public
returns (LibFillResults.FillResults memory totalFillResults);
/// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.
/// Returns false if the transaction would otherwise revert.
/// @param orders Array of order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell.
/// @param signatures Proofs that orders have been signed by makers.
/// @return Amounts filled and fees paid by makers and taker.
function marketSellOrdersNoThrow(
LibOrder.Order[] memory orders,
uint256 takerAssetFillAmount,
bytes[] memory signatures)
public
returns (LibFillResults.FillResults memory totalFillResults);
/// @dev Synchronously executes multiple calls of fillOrder until total amount of makerAsset is bought by taker.
/// @param orders Array of order specifications.
/// @param makerAssetFillAmount Desired amount of makerAsset to buy.
/// @param signatures Proofs that orders have been signed by makers.
/// @return Amounts filled and fees paid by makers and taker.
function marketBuyOrders(
LibOrder.Order[] memory orders,
uint256 makerAssetFillAmount,
bytes[] memory signatures)
public
returns (LibFillResults.FillResults memory totalFillResults);
/// @dev Synchronously executes multiple fill orders in a single transaction until total amount is bought by taker.
/// Returns false if the transaction would otherwise revert.
/// @param orders Array of order specifications.
/// @param makerAssetFillAmount Desired amount of makerAsset to buy.
/// @param signatures Proofs that orders have been signed by makers.
/// @return Amounts filled and fees paid by makers and taker.
function marketBuyOrdersNoThrow(
LibOrder.Order[] memory orders,
uint256 makerAssetFillAmount,
bytes[] memory signatures)
public
returns (LibFillResults.FillResults memory totalFillResults);
/// @dev Synchronously cancels multiple orders in a single transaction.
/// @param orders Array of order specifications.
function batchCancelOrders(LibOrder.Order[] memory orders)
public;
}

View File

@@ -17,9 +17,12 @@
*/
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
contract MAssetProxyDispatcher {
import "../interfaces/IAssetProxyDispatcher.sol";
contract MAssetProxyDispatcher is
IAssetProxyDispatcher
{
// Logs registration of new asset proxy
event AssetProxySet(
@@ -39,23 +42,4 @@ contract MAssetProxyDispatcher {
address to,
uint256 amount)
internal;
/// @dev Registers an asset proxy to an asset proxy id.
/// An id can only be assigned to a single proxy at a given time.
/// @param assetProxyId Id to register`newAssetProxy` under.
/// @param newAssetProxy Address of new asset proxy to register, or 0x0 to unset assetProxyId.
/// @param oldAssetProxy Existing asset proxy to overwrite, or 0x0 if assetProxyId is currently unused.
function registerAssetProxy(
uint8 assetProxyId,
address newAssetProxy,
address oldAssetProxy)
external;
/// @dev Gets an asset proxy.
/// @param assetProxyId Id of the asset proxy.
/// @return The asset proxy registered to assetProxyId. Returns 0x0 if no proxy is registered.
function getAssetProxy(uint8 assetProxyId)
external
view
returns (address);
}

View File

@@ -17,24 +17,50 @@
*/
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
import "../LibOrder.sol";
import "../LibFillResults.sol";
import "../lib/LibOrder.sol";
import "../lib/LibFillResults.sol";
import "../interfaces/IExchangeCore.sol";
contract MExchangeCore {
contract MExchangeCore is
IExchangeCore
{
function fillOrder(
// Fill event is emitted whenever an order is filled.
event Fill(
address indexed makerAddress,
address takerAddress,
address indexed feeRecipientAddress,
uint256 makerAssetFilledAmount,
uint256 takerAssetFilledAmount,
uint256 makerFeePaid,
uint256 takerFeePaid,
bytes32 indexed orderHash,
bytes makerAssetData,
bytes takerAssetData
);
// Cancel event is emitted whenever an individual order is cancelled.
event Cancel(
address indexed makerAddress,
address indexed feeRecipientAddress,
bytes32 indexed orderHash,
bytes makerAssetData,
bytes takerAssetData
);
// CancelUpTo event is emitted whenever `cancelOrdersUpTo` is executed succesfully.
event CancelUpTo(
address indexed makerAddress,
uint256 makerEpoch
);
/// @dev Logs a Fill event with the given arguments.
/// The sole purpose of this function is to get around the stack variable limit.
function emitFillEvent(
LibOrder.Order memory order,
uint256 takerAssetFillAmount,
bytes memory signature)
public
returns (LibFillResults.FillResults memory fillResults);
function cancelOrder(LibOrder.Order memory order)
public
returns (bool);
function cancelOrdersUpTo(uint256 salt)
external;
address takerAddress,
bytes32 orderHash,
LibFillResults.FillResults memory fillResults)
internal;
}

View File

@@ -17,12 +17,16 @@
*/
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
import "../LibOrder.sol";
import "../lib/LibOrder.sol";
contract MSettlement {
/// @dev Settles an order by transfering assets between counterparties.
/// @param order Order struct containing order specifications.
/// @param takerAddress Address selling takerAsset and buying makerAsset.
/// @param takerAssetFilledAmount The amount of takerAsset that will be transfered to the order's maker.
/// @return Amount filled by maker and fees paid by maker/taker.
function settleOrder(
LibOrder.Order memory order,
address takerAddress,

View File

@@ -17,9 +17,23 @@
*/
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
contract MSignatureValidator {
import "../interfaces/ISignatureValidator.sol";
contract MSignatureValidator is
ISignatureValidator
{
// Allowed signature types.
enum SignatureType {
Illegal, // Default value
Invalid,
Caller,
Ecrecover,
EIP712,
Trezor,
Contract,
PreSigned
}
/// @dev Verifies that a signature is valid.
/// @param hash Message hash that is signed.

View File

@@ -16,21 +16,12 @@
*/
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
contract MTransactions {
import "../interfaces/ITransactions.sol";
/// @dev Executes an exchange method call in the context of signer.
/// @param salt Arbitrary number to ensure uniqueness of transaction hash.
/// @param signer Address of transaction signer.
/// @param data AbiV2 encoded calldata.
/// @param signature Proof of signer transaction by signer.
function executeTransaction(
uint256 salt,
address signer,
bytes data,
bytes signature)
external;
contract MTransactions is
ITransactions
{
/// @dev The current function will be called in the context of this address (either 0x transaction signer or `msg.sender`).
/// If calling a fill function, this address will represent the taker.

View File

@@ -19,9 +19,9 @@
pragma solidity ^0.4.23;
pragma experimental ABIEncoderV2;
import "../../protocol/Exchange/LibMath.sol";
import "../../protocol/Exchange/LibOrder.sol";
import "../../protocol/Exchange/LibFillResults.sol";
import "../../protocol/Exchange/lib/LibMath.sol";
import "../../protocol/Exchange/lib/LibOrder.sol";
import "../../protocol/Exchange/lib/LibFillResults.sol";
contract TestLibs is
LibMath,