aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contracts/src
diff options
context:
space:
mode:
authorAmir Bandeali <abandeali1@gmail.com>2018-06-20 06:23:28 +0800
committerGitHub <noreply@github.com>2018-06-20 06:23:28 +0800
commite216eb1e7b49f1ad4bc2c8a07007b4ef94373c5d (patch)
tree70215e5dbf309870b9da483344ecd6f5678c5c4e /packages/contracts/src
parent0438fdde4919df13471f9b566b218ff9379d6d27 (diff)
parent6b08e6b80996d9553f280c6d7ade293ae7333711 (diff)
downloaddexon-0x-contracts-e216eb1e7b49f1ad4bc2c8a07007b4ef94373c5d.tar.gz
dexon-0x-contracts-e216eb1e7b49f1ad4bc2c8a07007b4ef94373c5d.tar.zst
dexon-0x-contracts-e216eb1e7b49f1ad4bc2c8a07007b4ef94373c5d.zip
Merge pull request #714 from 0xProject/feature/contracts/cancelOrdersUpToSender
Make cancelOrdersUpTo compatible with sender abstraction
Diffstat (limited to 'packages/contracts/src')
-rw-r--r--packages/contracts/src/contracts/current/protocol/Exchange/MixinExchangeCore.sol36
-rw-r--r--packages/contracts/src/contracts/current/protocol/Exchange/interfaces/IExchangeCore.sol7
-rw-r--r--packages/contracts/src/contracts/current/protocol/Exchange/libs/LibExchangeErrors.sol4
-rw-r--r--packages/contracts/src/contracts/current/protocol/Exchange/mixins/MExchangeCore.sol3
-rw-r--r--packages/contracts/src/contracts/current/test/ExchangeWrapper/ExchangeWrapper.sol98
-rw-r--r--packages/contracts/src/contracts/current/test/Whitelist/Whitelist.sol2
-rw-r--r--packages/contracts/src/utils/artifacts.ts2
7 files changed, 129 insertions, 23 deletions
diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/MixinExchangeCore.sol b/packages/contracts/src/contracts/current/protocol/Exchange/MixinExchangeCore.sol
index 0a0f0209a..c406354a7 100644
--- a/packages/contracts/src/contracts/current/protocol/Exchange/MixinExchangeCore.sol
+++ b/packages/contracts/src/contracts/current/protocol/Exchange/MixinExchangeCore.sol
@@ -44,32 +44,36 @@ contract MixinExchangeCore is
// Mapping of orderHash => cancelled
mapping (bytes32 => bool) public cancelled;
- // Mapping of makerAddress => lowest salt an order can have in order to be fillable
- // Orders with a salt less than their maker's epoch are considered cancelled
- mapping (address => uint256) public makerEpoch;
+ // Mapping of makerAddress => senderAddress => lowest salt an order can have in order to be fillable
+ // Orders with specified senderAddress and with a salt less than their epoch to are considered cancelled
+ mapping (address => mapping (address => uint256)) public orderEpoch;
////// Core exchange functions //////
- /// @dev Cancels all orders created 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)
+ /// @dev Cancels all orders created by makerAddress with a salt less than or equal to the targetOrderEpoch
+ /// and senderAddress equal to msg.sender (or null address if msg.sender == makerAddress).
+ /// @param targetOrderEpoch Orders created with a salt less or equal to this value will be cancelled.
+ function cancelOrdersUpTo(uint256 targetOrderEpoch)
external
{
address makerAddress = getCurrentContextAddress();
+ // If this function is called via `executeTransaction`, we only update the orderEpoch for the makerAddress/msg.sender combination.
+ // This allows external filter contracts to add rules to how orders are cancelled via this function.
+ address senderAddress = makerAddress == msg.sender ? address(0) : msg.sender;
- // makerEpoch is initialized to 0, so to cancelUpTo we need salt + 1
- uint256 newMakerEpoch = salt + 1;
- uint256 oldMakerEpoch = makerEpoch[makerAddress];
+ // orderEpoch is initialized to 0, so to cancelUpTo we need salt + 1
+ uint256 newOrderEpoch = targetOrderEpoch + 1;
+ uint256 oldOrderEpoch = orderEpoch[makerAddress][senderAddress];
- // Ensure makerEpoch is monotonically increasing
+ // Ensure orderEpoch is monotonically increasing
require(
- newMakerEpoch > oldMakerEpoch,
- INVALID_NEW_MAKER_EPOCH
+ newOrderEpoch > oldOrderEpoch,
+ INVALID_NEW_ORDER_EPOCH
);
- // Update makerEpoch
- makerEpoch[makerAddress] = newMakerEpoch;
- emit CancelUpTo(makerAddress, newMakerEpoch);
+ // Update orderEpoch
+ orderEpoch[makerAddress][senderAddress] = newOrderEpoch;
+ emit CancelUpTo(makerAddress, senderAddress, newOrderEpoch);
}
/// @dev Fills the input order.
@@ -180,7 +184,7 @@ contract MixinExchangeCore is
orderInfo.orderStatus = uint8(OrderStatus.CANCELLED);
return orderInfo;
}
- if (makerEpoch[order.makerAddress] > order.salt) {
+ if (orderEpoch[order.makerAddress][order.senderAddress] > order.salt) {
orderInfo.orderStatus = uint8(OrderStatus.CANCELLED);
return orderInfo;
}
diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/interfaces/IExchangeCore.sol b/packages/contracts/src/contracts/current/protocol/Exchange/interfaces/IExchangeCore.sol
index 7ca2dd052..98222f33f 100644
--- a/packages/contracts/src/contracts/current/protocol/Exchange/interfaces/IExchangeCore.sol
+++ b/packages/contracts/src/contracts/current/protocol/Exchange/interfaces/IExchangeCore.sol
@@ -24,9 +24,10 @@ import "../libs/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)
+ /// @dev Cancels all orders created by makerAddress with a salt less than or equal to the targetOrderEpoch
+ /// and senderAddress equal to msg.sender (or null address if msg.sender == makerAddress).
+ /// @param targetOrderEpoch Orders created with a salt less or equal to this value will be cancelled.
+ function cancelOrdersUpTo(uint256 targetOrderEpoch)
external;
/// @dev Fills the input order.
diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/libs/LibExchangeErrors.sol b/packages/contracts/src/contracts/current/protocol/Exchange/libs/LibExchangeErrors.sol
index 48dd0f8be..adf27bec3 100644
--- a/packages/contracts/src/contracts/current/protocol/Exchange/libs/LibExchangeErrors.sol
+++ b/packages/contracts/src/contracts/current/protocol/Exchange/libs/LibExchangeErrors.sol
@@ -36,7 +36,7 @@ contract LibExchangeErrors {
string constant SIGNATURE_UNSUPPORTED = "SIGNATURE_UNSUPPORTED"; // Signature type unsupported.
/// cancelOrdersUptTo errors ///
- string constant INVALID_NEW_MAKER_EPOCH = "INVALID_NEW_MAKER_EPOCH"; // Specified salt must be greater than or equal to existing makerEpoch.
+ string constant INVALID_NEW_ORDER_EPOCH = "INVALID_NEW_ORDER_EPOCH"; // Specified salt must be greater than or equal to existing orderEpoch.
/// fillOrKillOrder errors ///
string constant COMPLETE_FILL_FAILED = "COMPLETE_FILL_FAILED"; // Desired takerAssetFillAmount could not be completely filled.
@@ -55,7 +55,7 @@ contract LibExchangeErrors {
string constant ASSET_PROXY_ID_MISMATCH = "ASSET_PROXY_ID_MISMATCH"; // newAssetProxyId does not match given assetProxyId.
/// Length validation errors ///
- string constant LENGTH_GREATER_THAN_0_REQUIRED = "LENGTH_GREATER_THAN_0_REQUIRED"; // Byte array must have a length greater than 0.
+ string constant LENGTH_GREATER_THAN_0_REQUIRED = "LENGTH_GREATER_THAN_0_REQUIRED"; // Byte array must have a length greater than 0.
string constant LENGTH_0_REQUIRED = "LENGTH_1_REQUIRED"; // Byte array must have a length of 1.
string constant LENGTH_65_REQUIRED = "LENGTH_66_REQUIRED"; // Byte array must have a length of 66.
}
diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/mixins/MExchangeCore.sol b/packages/contracts/src/contracts/current/protocol/Exchange/mixins/MExchangeCore.sol
index de7c4d3af..fb345294c 100644
--- a/packages/contracts/src/contracts/current/protocol/Exchange/mixins/MExchangeCore.sol
+++ b/packages/contracts/src/contracts/current/protocol/Exchange/mixins/MExchangeCore.sol
@@ -52,7 +52,8 @@ contract MExchangeCore is
// CancelUpTo event is emitted whenever `cancelOrdersUpTo` is executed succesfully.
event CancelUpTo(
address indexed makerAddress,
- uint256 makerEpoch
+ address indexed senderAddress,
+ uint256 orderEpoch
);
/// @dev Updates state with results of a fill order.
diff --git a/packages/contracts/src/contracts/current/test/ExchangeWrapper/ExchangeWrapper.sol b/packages/contracts/src/contracts/current/test/ExchangeWrapper/ExchangeWrapper.sol
new file mode 100644
index 000000000..5baaf6e5a
--- /dev/null
+++ b/packages/contracts/src/contracts/current/test/ExchangeWrapper/ExchangeWrapper.sol
@@ -0,0 +1,98 @@
+/*
+
+ 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.24;
+pragma experimental ABIEncoderV2;
+
+import "../../protocol/Exchange/interfaces/IExchange.sol";
+import "../../protocol/Exchange/libs/LibOrder.sol";
+
+contract ExchangeWrapper {
+
+ // Exchange contract.
+ IExchange EXCHANGE;
+
+ constructor (address _exchange)
+ public
+ {
+ EXCHANGE = IExchange(_exchange);
+ }
+
+ /// @dev Fills an order using `msg.sender` as the taker.
+ /// @param order Order struct containing order specifications.
+ /// @param takerAssetFillAmount Desired amount of takerAsset to sell.
+ /// @param salt Arbitrary value to gaurantee uniqueness of 0x transaction hash.
+ /// @param orderSignature Proof that order has been created by maker.
+ /// @param takerSignature Proof that taker wishes to call this function with given params.
+ function fillOrder(
+ LibOrder.Order memory order,
+ uint256 takerAssetFillAmount,
+ uint256 salt,
+ bytes memory orderSignature,
+ bytes memory takerSignature
+ )
+ public
+ {
+ address takerAddress = msg.sender;
+
+ // Encode arguments into byte array.
+ bytes memory data = abi.encodeWithSelector(
+ EXCHANGE.fillOrder.selector,
+ order,
+ takerAssetFillAmount,
+ orderSignature
+ );
+
+ // Call `fillOrder` via `executeTransaction`.
+ EXCHANGE.executeTransaction(
+ salt,
+ takerAddress,
+ data,
+ takerSignature
+ );
+ }
+
+ /// @dev Cancels all orders created by sender with a salt less than or equal to the targetOrderEpoch
+ /// and senderAddress equal to this contract.
+ /// @param targetOrderEpoch Orders created with a salt less or equal to this value will be cancelled.
+ /// @param salt Arbitrary value to gaurantee uniqueness of 0x transaction hash.
+ /// @param makerSignature Proof that maker wishes to call this function with given params.
+ function cancelOrdersUpTo(
+ uint256 targetOrderEpoch,
+ uint256 salt,
+ bytes makerSignature
+ )
+ external
+ {
+ address makerAddress = msg.sender;
+
+ // Encode arguments into byte array.
+ bytes memory data = abi.encodeWithSelector(
+ EXCHANGE.cancelOrdersUpTo.selector,
+ targetOrderEpoch
+ );
+
+ // Call `cancelOrdersUpTo` via `executeTransaction`.
+ EXCHANGE.executeTransaction(
+ salt,
+ makerAddress,
+ data,
+ makerSignature
+ );
+ }
+}
diff --git a/packages/contracts/src/contracts/current/test/Whitelist/Whitelist.sol b/packages/contracts/src/contracts/current/test/Whitelist/Whitelist.sol
index 0594e2767..460c9ea42 100644
--- a/packages/contracts/src/contracts/current/test/Whitelist/Whitelist.sol
+++ b/packages/contracts/src/contracts/current/test/Whitelist/Whitelist.sol
@@ -16,7 +16,7 @@
*/
-pragma solidity ^0.4.23;
+pragma solidity ^0.4.24;
pragma experimental ABIEncoderV2;
import "../../protocol/Exchange/interfaces/IExchange.sol";
diff --git a/packages/contracts/src/utils/artifacts.ts b/packages/contracts/src/utils/artifacts.ts
index bf7221d6d..7ba467708 100644
--- a/packages/contracts/src/utils/artifacts.ts
+++ b/packages/contracts/src/utils/artifacts.ts
@@ -7,6 +7,7 @@ import * as DummyERC721Token from '../artifacts/DummyERC721Token.json';
import * as ERC20Proxy from '../artifacts/ERC20Proxy.json';
import * as ERC721Proxy from '../artifacts/ERC721Proxy.json';
import * as Exchange from '../artifacts/Exchange.json';
+import * as ExchangeWrapper from '../artifacts/ExchangeWrapper.json';
import * as MixinAuthorizable from '../artifacts/MixinAuthorizable.json';
import * as MultiSigWallet from '../artifacts/MultiSigWallet.json';
import * as MultiSigWalletWithTimeLock from '../artifacts/MultiSigWalletWithTimeLock.json';
@@ -29,6 +30,7 @@ export const artifacts = {
ERC20Proxy: (ERC20Proxy as any) as ContractArtifact,
ERC721Proxy: (ERC721Proxy as any) as ContractArtifact,
Exchange: (Exchange as any) as ContractArtifact,
+ ExchangeWrapper: (ExchangeWrapper as any) as ContractArtifact,
EtherToken: (EtherToken as any) as ContractArtifact,
MixinAuthorizable: (MixinAuthorizable as any) as ContractArtifact,
MultiSigWallet: (MultiSigWallet as any) as ContractArtifact,