aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contracts/src
diff options
context:
space:
mode:
authorAmir Bandeali <abandeali1@gmail.com>2018-08-22 07:06:21 +0800
committerAmir Bandeali <abandeali1@gmail.com>2018-08-25 08:30:56 +0800
commit6f88e9bdbdd8f44c45053b8c17c84411f9499084 (patch)
tree54130461d0a157ccc89a0c018bb6d341a9d0262b /packages/contracts/src
parentd8cb56caa33885397f557afac5a4ccb24efb47d0 (diff)
downloaddexon-0x-contracts-6f88e9bdbdd8f44c45053b8c17c84411f9499084.tar.gz
dexon-0x-contracts-6f88e9bdbdd8f44c45053b8c17c84411f9499084.tar.zst
dexon-0x-contracts-6f88e9bdbdd8f44c45053b8c17c84411f9499084.zip
Add internal fill functions, add reentrancy guard to public functions that make external calls
Diffstat (limited to 'packages/contracts/src')
-rw-r--r--packages/contracts/src/2.0.0/protocol/Exchange/MixinExchangeCore.sol86
-rw-r--r--packages/contracts/src/2.0.0/protocol/Exchange/MixinMatchOrders.sol3
-rw-r--r--packages/contracts/src/2.0.0/protocol/Exchange/MixinWrapperFunctions.sol46
-rw-r--r--packages/contracts/src/2.0.0/protocol/Exchange/mixins/MExchangeCore.sol13
-rw-r--r--packages/contracts/src/2.0.0/protocol/Exchange/mixins/MWrapperFunctions.sol40
-rw-r--r--packages/contracts/src/2.0.0/utils/ReentrancyGuard/ReentrancyGuard.sol1
6 files changed, 148 insertions, 41 deletions
diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/MixinExchangeCore.sol b/packages/contracts/src/2.0.0/protocol/Exchange/MixinExchangeCore.sol
index f3a0591b2..d00323b15 100644
--- a/packages/contracts/src/2.0.0/protocol/Exchange/MixinExchangeCore.sol
+++ b/packages/contracts/src/2.0.0/protocol/Exchange/MixinExchangeCore.sol
@@ -19,6 +19,7 @@
pragma solidity 0.4.24;
pragma experimental ABIEncoderV2;
+import "../../utils/ReentrancyGuard/ReentrancyGuard.sol";
import "./libs/LibConstants.sol";
import "./libs/LibFillResults.sol";
import "./libs/LibOrder.sol";
@@ -30,6 +31,7 @@ import "./mixins/MAssetProxyDispatcher.sol";
contract MixinExchangeCore is
+ ReentrancyGuard,
LibConstants,
LibMath,
LibOrder,
@@ -86,43 +88,14 @@ contract MixinExchangeCore is
bytes memory signature
)
public
+ nonReentrant
returns (FillResults memory fillResults)
{
- // Fetch order info
- OrderInfo memory orderInfo = getOrderInfo(order);
-
- // Fetch taker address
- address takerAddress = getCurrentContextAddress();
-
- // Get amount of takerAsset to fill
- uint256 remainingTakerAssetAmount = safeSub(order.takerAssetAmount, orderInfo.orderTakerAssetFilledAmount);
- uint256 takerAssetFilledAmount = min256(takerAssetFillAmount, remainingTakerAssetAmount);
-
- // Validate context
- assertValidFill(
+ fillResults = fillOrderInternal(
order,
- orderInfo,
- takerAddress,
takerAssetFillAmount,
- takerAssetFilledAmount,
signature
);
-
- // Compute proportional fill amounts
- fillResults = calculateFillResults(order, takerAssetFilledAmount);
-
- // Update exchange internal state
- updateFilledState(
- order,
- takerAddress,
- orderInfo.orderHash,
- orderInfo.orderTakerAssetFilledAmount,
- fillResults
- );
-
- // Settle order
- settleOrder(order, takerAddress, fillResults);
-
return fillResults;
}
@@ -203,6 +176,57 @@ contract MixinExchangeCore is
return orderInfo;
}
+ /// @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 fillOrderInternal(
+ Order memory order,
+ uint256 takerAssetFillAmount,
+ bytes memory signature
+ )
+ internal
+ returns (FillResults memory fillResults)
+ {
+ // Fetch order info
+ OrderInfo memory orderInfo = getOrderInfo(order);
+
+ // Fetch taker address
+ address takerAddress = getCurrentContextAddress();
+
+ // Get amount of takerAsset to fill
+ uint256 remainingTakerAssetAmount = safeSub(order.takerAssetAmount, orderInfo.orderTakerAssetFilledAmount);
+ uint256 takerAssetFilledAmount = min256(takerAssetFillAmount, remainingTakerAssetAmount);
+
+ // Validate context
+ assertValidFill(
+ order,
+ orderInfo,
+ takerAddress,
+ takerAssetFillAmount,
+ takerAssetFilledAmount,
+ signature
+ );
+
+ // Compute proportional fill amounts
+ fillResults = calculateFillResults(order, takerAssetFilledAmount);
+
+ // Update exchange internal state
+ updateFilledState(
+ order,
+ takerAddress,
+ orderInfo.orderHash,
+ orderInfo.orderTakerAssetFilledAmount,
+ fillResults
+ );
+
+ // Settle order
+ settleOrder(order, takerAddress, fillResults);
+
+ return fillResults;
+ }
+
/// @dev Updates state with results of a fill order.
/// @param order that was filled.
/// @param takerAddress Address of taker who filled the order.
diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/MixinMatchOrders.sol b/packages/contracts/src/2.0.0/protocol/Exchange/MixinMatchOrders.sol
index 20f4b1c33..25220a673 100644
--- a/packages/contracts/src/2.0.0/protocol/Exchange/MixinMatchOrders.sol
+++ b/packages/contracts/src/2.0.0/protocol/Exchange/MixinMatchOrders.sol
@@ -14,6 +14,7 @@
pragma solidity 0.4.24;
pragma experimental ABIEncoderV2;
+import "../../utils/ReentrancyGuard/ReentrancyGuard.sol";
import "./libs/LibConstants.sol";
import "./libs/LibMath.sol";
import "./libs/LibOrder.sol";
@@ -25,6 +26,7 @@ import "./mixins/MAssetProxyDispatcher.sol";
contract MixinMatchOrders is
+ ReentrancyGuard,
LibConstants,
LibMath,
MAssetProxyDispatcher,
@@ -48,6 +50,7 @@ contract MixinMatchOrders is
bytes memory rightSignature
)
public
+ nonReentrant
returns (LibFillResults.MatchedFillResults memory matchedFillResults)
{
// We assume that rightOrder.takerAssetData == leftOrder.makerAssetData and rightOrder.makerAssetData == leftOrder.takerAssetData.
diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/MixinWrapperFunctions.sol b/packages/contracts/src/2.0.0/protocol/Exchange/MixinWrapperFunctions.sol
index 1b77cfbcb..ff1cb6995 100644
--- a/packages/contracts/src/2.0.0/protocol/Exchange/MixinWrapperFunctions.sol
+++ b/packages/contracts/src/2.0.0/protocol/Exchange/MixinWrapperFunctions.sol
@@ -19,14 +19,17 @@
pragma solidity 0.4.24;
pragma experimental ABIEncoderV2;
+import "../../utils/ReentrancyGuard/ReentrancyGuard.sol";
import "./libs/LibMath.sol";
import "./libs/LibOrder.sol";
import "./libs/LibFillResults.sol";
import "./libs/LibAbiEncoder.sol";
import "./mixins/MExchangeCore.sol";
+import "./mixins/MWrapperFunctions.sol";
contract MixinWrapperFunctions is
+ ReentrancyGuard,
LibMath,
LibFillResults,
LibAbiEncoder,
@@ -43,17 +46,14 @@ contract MixinWrapperFunctions is
bytes memory signature
)
public
+ nonReentrant
returns (FillResults memory fillResults)
{
- fillResults = fillOrder(
+ fillResults = fillOrKillOrderInternal(
order,
takerAssetFillAmount,
signature
);
- require(
- fillResults.takerAssetFilledAmount == takerAssetFillAmount,
- "COMPLETE_FILL_FAILED"
- );
return fillResults;
}
@@ -117,11 +117,12 @@ contract MixinWrapperFunctions is
bytes[] memory signatures
)
public
+ nonReentrant
returns (FillResults memory totalFillResults)
{
uint256 ordersLength = orders.length;
for (uint256 i = 0; i != ordersLength; i++) {
- FillResults memory singleFillResults = fillOrder(
+ FillResults memory singleFillResults = fillOrderInternal(
orders[i],
takerAssetFillAmounts[i],
signatures[i]
@@ -143,11 +144,12 @@ contract MixinWrapperFunctions is
bytes[] memory signatures
)
public
+ nonReentrant
returns (FillResults memory totalFillResults)
{
uint256 ordersLength = orders.length;
for (uint256 i = 0; i != ordersLength; i++) {
- FillResults memory singleFillResults = fillOrKillOrder(
+ FillResults memory singleFillResults = fillOrKillOrderInternal(
orders[i],
takerAssetFillAmounts[i],
signatures[i]
@@ -195,6 +197,7 @@ contract MixinWrapperFunctions is
bytes[] memory signatures
)
public
+ nonReentrant
returns (FillResults memory totalFillResults)
{
bytes memory takerAssetData = orders[0].takerAssetData;
@@ -210,7 +213,7 @@ contract MixinWrapperFunctions is
uint256 remainingTakerAssetFillAmount = safeSub(takerAssetFillAmount, totalFillResults.takerAssetFilledAmount);
// Attempt to sell the remaining amount of takerAsset
- FillResults memory singleFillResults = fillOrder(
+ FillResults memory singleFillResults = fillOrderInternal(
orders[i],
remainingTakerAssetFillAmount,
signatures[i]
@@ -282,6 +285,7 @@ contract MixinWrapperFunctions is
bytes[] memory signatures
)
public
+ nonReentrant
returns (FillResults memory totalFillResults)
{
bytes memory makerAssetData = orders[0].makerAssetData;
@@ -305,7 +309,7 @@ contract MixinWrapperFunctions is
);
// Attempt to sell the remaining amount of takerAsset
- FillResults memory singleFillResults = fillOrder(
+ FillResults memory singleFillResults = fillOrderInternal(
orders[i],
remainingTakerAssetFillAmount,
signatures[i]
@@ -400,4 +404,28 @@ contract MixinWrapperFunctions is
}
return ordersInfo;
}
+
+ /// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled.
+ /// @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.
+ function fillOrKillOrderInternal(
+ LibOrder.Order memory order,
+ uint256 takerAssetFillAmount,
+ bytes memory signature
+ )
+ internal
+ returns (FillResults memory fillResults)
+ {
+ fillResults = fillOrderInternal(
+ order,
+ takerAssetFillAmount,
+ signature
+ );
+ require(
+ fillResults.takerAssetFilledAmount == takerAssetFillAmount,
+ "COMPLETE_FILL_FAILED"
+ );
+ return fillResults;
+ }
}
diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MExchangeCore.sol b/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MExchangeCore.sol
index c165b647c..41832fe4b 100644
--- a/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MExchangeCore.sol
+++ b/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MExchangeCore.sol
@@ -59,6 +59,19 @@ contract MExchangeCore is
uint256 orderEpoch // Orders with specified makerAddress and senderAddress with a salt less than this value are considered cancelled.
);
+ /// @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 fillOrderInternal(
+ LibOrder.Order memory order,
+ uint256 takerAssetFillAmount,
+ bytes memory signature
+ )
+ internal
+ returns (LibFillResults.FillResults memory fillResults);
+
/// @dev Updates state with results of a fill order.
/// @param order that was filled.
/// @param takerAddress Address of taker who filled the order.
diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MWrapperFunctions.sol b/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MWrapperFunctions.sol
new file mode 100644
index 000000000..e04d4a429
--- /dev/null
+++ b/packages/contracts/src/2.0.0/protocol/Exchange/mixins/MWrapperFunctions.sol
@@ -0,0 +1,40 @@
+/*
+
+ 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 "../libs/LibOrder.sol";
+import "../libs/LibFillResults.sol";
+import "../interfaces/IWrapperFunctions.sol";
+
+
+contract MWrapperFunctions {
+
+ /// @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 fillOrKillOrderInternal(
+ LibOrder.Order memory order,
+ uint256 takerAssetFillAmount,
+ bytes memory signature
+ )
+ internal
+ returns (LibFillResults.FillResults memory fillResults);
+}
diff --git a/packages/contracts/src/2.0.0/utils/ReentrancyGuard/ReentrancyGuard.sol b/packages/contracts/src/2.0.0/utils/ReentrancyGuard/ReentrancyGuard.sol
index 70fc4ca6b..5d6f6970d 100644
--- a/packages/contracts/src/2.0.0/utils/ReentrancyGuard/ReentrancyGuard.sol
+++ b/packages/contracts/src/2.0.0/utils/ReentrancyGuard/ReentrancyGuard.sol
@@ -40,5 +40,4 @@ contract ReentrancyGuard {
// Unlock mutex after function call
locked = false;
}
-
}