diff options
author | Amir Bandeali <abandeali1@gmail.com> | 2018-06-20 06:23:28 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-20 06:23:28 +0800 |
commit | e216eb1e7b49f1ad4bc2c8a07007b4ef94373c5d (patch) | |
tree | 70215e5dbf309870b9da483344ecd6f5678c5c4e /packages/contracts/src | |
parent | 0438fdde4919df13471f9b566b218ff9379d6d27 (diff) | |
parent | 6b08e6b80996d9553f280c6d7ade293ae7333711 (diff) | |
download | dexon-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')
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, |