diff options
Diffstat (limited to 'packages/contracts/src/2.0.0/forwarder')
10 files changed, 98 insertions, 84 deletions
diff --git a/packages/contracts/src/2.0.0/forwarder/Forwarder.sol b/packages/contracts/src/2.0.0/forwarder/Forwarder.sol index 71a4aff13..38128d93e 100644 --- a/packages/contracts/src/2.0.0/forwarder/Forwarder.sol +++ b/packages/contracts/src/2.0.0/forwarder/Forwarder.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "./MixinWethFees.sol"; @@ -25,6 +25,7 @@ import "./MixinMarketBuyTokens.sol"; import "./MixinConstants.sol"; import "../utils/Ownable/Ownable.sol"; + contract Forwarder is Ownable, MixinConstants, @@ -33,7 +34,7 @@ contract Forwarder is MixinMarketBuyTokens, MixinMarketSellTokens { - uint256 MAX_UINT = 2**256 - 1; + uint256 constant internal MAX_UINT = 2**256 - 1; constructor ( address _exchange, diff --git a/packages/contracts/src/2.0.0/forwarder/MixinConstants.sol b/packages/contracts/src/2.0.0/forwarder/MixinConstants.sol index 18f2ba3bc..ea82e9d64 100644 --- a/packages/contracts/src/2.0.0/forwarder/MixinConstants.sol +++ b/packages/contracts/src/2.0.0/forwarder/MixinConstants.sol @@ -16,19 +16,22 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; import "../protocol/Exchange/Exchange.sol"; import { WETH9 as EtherToken } from "../tokens/WETH9/WETH9.sol"; import "../tokens/ERC20Token/IERC20Token.sol"; + contract MixinConstants { - Exchange EXCHANGE; - EtherToken ETHER_TOKEN; - IERC20Token ZRX_TOKEN; - bytes ZRX_ASSET_DATA; - bytes WETH_ASSET_DATA; + // solhint-disable var-name-mixedcase + Exchange internal EXCHANGE; + EtherToken internal ETHER_TOKEN; + IERC20Token internal ZRX_TOKEN; + bytes internal ZRX_ASSET_DATA; + bytes internal WETH_ASSET_DATA; + // solhint-enable var-name-mixedcase constructor ( address _exchange, diff --git a/packages/contracts/src/2.0.0/forwarder/MixinERC20.sol b/packages/contracts/src/2.0.0/forwarder/MixinERC20.sol index 53d4116d7..387c3de6b 100644 --- a/packages/contracts/src/2.0.0/forwarder/MixinERC20.sol +++ b/packages/contracts/src/2.0.0/forwarder/MixinERC20.sol @@ -16,13 +16,13 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; + contract MixinERC20 { - string constant ERROR_TRANSFER_FAILED = "TRANSFER_FAILED"; - bytes4 constant ERC20_TRANSFER_SELECTOR = bytes4(keccak256("transfer(address,uint256)")); + bytes4 constant internal ERC20_TRANSFER_SELECTOR = bytes4(keccak256("transfer(address,uint256)")); function transferToken( address token, diff --git a/packages/contracts/src/2.0.0/forwarder/MixinERC721.sol b/packages/contracts/src/2.0.0/forwarder/MixinERC721.sol index b2e8803a9..b5be223b6 100644 --- a/packages/contracts/src/2.0.0/forwarder/MixinERC721.sol +++ b/packages/contracts/src/2.0.0/forwarder/MixinERC721.sol @@ -16,17 +16,19 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../utils/LibBytes/LibBytes.sol"; import "../tokens/ERC721Token/IERC721Token.sol"; + contract MixinERC721 { using LibBytes for bytes; - bytes4 constant ERC721_RECEIVED = bytes4(keccak256("onERC721Received(address,uint256,bytes)")); - bytes4 constant ERC721_RECEIVED_OPERATOR = bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")); + + bytes4 constant internal ERC721_RECEIVED = bytes4(keccak256("onERC721Received(address,uint256,bytes)")); + bytes4 constant internal ERC721_RECEIVED_OPERATOR = bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")); function onERC721Received(address, uint256, bytes memory) public diff --git a/packages/contracts/src/2.0.0/forwarder/MixinErrorMessages.sol b/packages/contracts/src/2.0.0/forwarder/MixinErrorMessages.sol index c2a6ea0a4..1b3e3f488 100644 --- a/packages/contracts/src/2.0.0/forwarder/MixinErrorMessages.sol +++ b/packages/contracts/src/2.0.0/forwarder/MixinErrorMessages.sol @@ -16,7 +16,9 @@ */ -pragma solidity ^0.4.24; +// solhint-disable +pragma solidity 0.4.24; + /// This contract is intended to serve as a reference, but is not actually used for efficiency reasons. contract MixinErrorMessages { diff --git a/packages/contracts/src/2.0.0/forwarder/MixinExpectedResults.sol b/packages/contracts/src/2.0.0/forwarder/MixinExpectedResults.sol index 0bca7dc80..6406d1d37 100644 --- a/packages/contracts/src/2.0.0/forwarder/MixinExpectedResults.sol +++ b/packages/contracts/src/2.0.0/forwarder/MixinExpectedResults.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../utils/LibBytes/LibBytes.sol"; @@ -25,74 +25,13 @@ import "../protocol/Exchange/libs/LibMath.sol"; import "../protocol/Exchange/libs/LibOrder.sol"; import "./MixinConstants.sol"; + contract MixinExpectedResults is LibMath, LibFillResults, MixinConstants { - /// @dev Simulates the 0x Exchange fillOrder validation and calculations, without performing any state changes. - /// @param order An Order struct containing order specifications. - /// @param takerAssetFillAmount A number representing the amount of this order to fill. - /// @return fillResults Amounts filled and fees paid by maker and taker. - function calculateFillResults( - LibOrder.Order memory order, - uint256 takerAssetFillAmount - ) - internal - view - returns (FillResults memory fillResults) - { - LibOrder.OrderInfo memory orderInfo = EXCHANGE.getOrderInfo(order); - if (orderInfo.orderStatus != uint8(LibOrder.OrderStatus.FILLABLE)) { - return fillResults; - } - uint256 remainingTakerAssetAmount = safeSub(order.takerAssetAmount, orderInfo.orderTakerAssetFilledAmount); - uint256 takerAssetFilledAmount = min256(takerAssetFillAmount, remainingTakerAssetAmount); - - fillResults.takerAssetFilledAmount = takerAssetFilledAmount; - fillResults.makerAssetFilledAmount = getPartialAmount( - takerAssetFilledAmount, - order.takerAssetAmount, - order.makerAssetAmount - ); - fillResults.makerFeePaid = getPartialAmount( - takerAssetFilledAmount, - order.takerAssetAmount, - order.makerFee - ); - fillResults.takerFeePaid = getPartialAmount( - takerAssetFilledAmount, - order.takerAssetAmount, - order.takerFee - ); - return fillResults; - } - - /// @dev Calculates a FillResults total for selling takerAssetFillAmount over all orders. - /// Including the fees required to be paid. - /// @param orders An array of Order struct containing order specifications. - /// @param takerAssetFillAmount A number representing the amount of this order to fill. - /// @return totalFillResults Amounts filled and fees paid by maker and taker. - function calculateMarketSellResults( - LibOrder.Order[] memory orders, - uint256 takerAssetFillAmount - ) - internal - view - returns (FillResults memory totalFillResults) - { - for (uint256 i = 0; i < orders.length; i++) { - uint256 remainingTakerAssetFillAmount = safeSub(takerAssetFillAmount, totalFillResults.takerAssetFilledAmount); - FillResults memory singleFillResult = calculateFillResults(orders[i], remainingTakerAssetFillAmount); - addFillResults(totalFillResults, singleFillResult); - if (totalFillResults.takerAssetFilledAmount == takerAssetFillAmount) { - break; - } - } - return totalFillResults; - } - /// @dev Calculates a total FillResults for buying makerAssetFillAmount over all orders. /// Including the fees required to be paid. /// @param orders An array of Order struct containing order specifications. @@ -155,4 +94,66 @@ contract MixinExpectedResults is } return totalFillResults; } + + /// @dev Simulates the 0x Exchange fillOrder validation and calculations, without performing any state changes. + /// @param order An Order struct containing order specifications. + /// @param takerAssetFillAmount A number representing the amount of this order to fill. + /// @return fillResults Amounts filled and fees paid by maker and taker. + function calculateFillResults( + LibOrder.Order memory order, + uint256 takerAssetFillAmount + ) + internal + view + returns (FillResults memory fillResults) + { + LibOrder.OrderInfo memory orderInfo = EXCHANGE.getOrderInfo(order); + if (orderInfo.orderStatus != uint8(LibOrder.OrderStatus.FILLABLE)) { + return fillResults; + } + uint256 remainingTakerAssetAmount = safeSub(order.takerAssetAmount, orderInfo.orderTakerAssetFilledAmount); + uint256 takerAssetFilledAmount = min256(takerAssetFillAmount, remainingTakerAssetAmount); + + fillResults.takerAssetFilledAmount = takerAssetFilledAmount; + fillResults.makerAssetFilledAmount = getPartialAmount( + takerAssetFilledAmount, + order.takerAssetAmount, + order.makerAssetAmount + ); + fillResults.makerFeePaid = getPartialAmount( + takerAssetFilledAmount, + order.takerAssetAmount, + order.makerFee + ); + fillResults.takerFeePaid = getPartialAmount( + takerAssetFilledAmount, + order.takerAssetAmount, + order.takerFee + ); + return fillResults; + } + + /// @dev Calculates a FillResults total for selling takerAssetFillAmount over all orders. + /// Including the fees required to be paid. + /// @param orders An array of Order struct containing order specifications. + /// @param takerAssetFillAmount A number representing the amount of this order to fill. + /// @return totalFillResults Amounts filled and fees paid by maker and taker. + function calculateMarketSellResults( + LibOrder.Order[] memory orders, + uint256 takerAssetFillAmount + ) + internal + view + returns (FillResults memory totalFillResults) + { + for (uint256 i = 0; i < orders.length; i++) { + uint256 remainingTakerAssetFillAmount = safeSub(takerAssetFillAmount, totalFillResults.takerAssetFilledAmount); + FillResults memory singleFillResult = calculateFillResults(orders[i], remainingTakerAssetFillAmount); + addFillResults(totalFillResults, singleFillResult); + if (totalFillResults.takerAssetFilledAmount == takerAssetFillAmount) { + break; + } + } + return totalFillResults; + } } diff --git a/packages/contracts/src/2.0.0/forwarder/MixinMarketBuyTokens.sol b/packages/contracts/src/2.0.0/forwarder/MixinMarketBuyTokens.sol index ef06fe519..165fec61f 100644 --- a/packages/contracts/src/2.0.0/forwarder/MixinMarketBuyTokens.sol +++ b/packages/contracts/src/2.0.0/forwarder/MixinMarketBuyTokens.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../utils/LibBytes/LibBytes.sol"; @@ -28,6 +28,7 @@ import "./MixinERC721.sol"; import "./MixinConstants.sol"; import "../protocol/Exchange/libs/LibOrder.sol"; + contract MixinMarketBuyTokens is MixinConstants, MixinWethFees, @@ -62,8 +63,8 @@ contract MixinMarketBuyTokens is uint16 feeProportion, address feeRecipient ) - payable public + payable returns (FillResults memory totalFillResults) { uint256 takerEthAmount = msg.value; diff --git a/packages/contracts/src/2.0.0/forwarder/MixinMarketBuyZrx.sol b/packages/contracts/src/2.0.0/forwarder/MixinMarketBuyZrx.sol index 4dbb34de3..cc98cb63d 100644 --- a/packages/contracts/src/2.0.0/forwarder/MixinMarketBuyZrx.sol +++ b/packages/contracts/src/2.0.0/forwarder/MixinMarketBuyZrx.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../protocol/Exchange/Exchange.sol"; @@ -25,11 +25,13 @@ import "../protocol/Exchange/libs/LibOrder.sol"; import "../protocol/Exchange/libs/LibMath.sol"; import "./MixinConstants.sol"; + contract MixinMarketBuyZrx is LibMath, LibFillResults, MixinConstants { + /// @dev Buys zrxBuyAmount of ZRX fee tokens, taking into account the fees on buying fee tokens. This will guarantee /// At least zrxBuyAmount of ZRX fee tokens are purchased (sometimes slightly over due to rounding issues). /// It is possible that a request to buy 200 ZRX fee tokens will require purchasing 202 ZRX tokens diff --git a/packages/contracts/src/2.0.0/forwarder/MixinMarketSellTokens.sol b/packages/contracts/src/2.0.0/forwarder/MixinMarketSellTokens.sol index 8c9cdb8d5..f4f509846 100644 --- a/packages/contracts/src/2.0.0/forwarder/MixinMarketSellTokens.sol +++ b/packages/contracts/src/2.0.0/forwarder/MixinMarketSellTokens.sol @@ -16,7 +16,7 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import "../protocol/Exchange/libs/LibOrder.sol"; @@ -27,6 +27,7 @@ import "./MixinERC20.sol"; import "./MixinConstants.sol"; import "./MixinMarketBuyZrx.sol"; + contract MixinMarketSellTokens is MixinConstants, MixinWethFees, @@ -55,8 +56,8 @@ contract MixinMarketSellTokens is uint16 feeProportion, address feeRecipient ) - payable public + payable returns (FillResults memory totalFillResults) { uint256 takerEthAmount = msg.value; diff --git a/packages/contracts/src/2.0.0/forwarder/MixinWethFees.sol b/packages/contracts/src/2.0.0/forwarder/MixinWethFees.sol index 9206c5fe0..92e2cebe8 100644 --- a/packages/contracts/src/2.0.0/forwarder/MixinWethFees.sol +++ b/packages/contracts/src/2.0.0/forwarder/MixinWethFees.sol @@ -16,13 +16,14 @@ */ -pragma solidity ^0.4.24; +pragma solidity 0.4.24; pragma experimental ABIEncoderV2; import { WETH9 as EtherToken } from "../tokens/WETH9/WETH9.sol"; import "../protocol/Exchange/libs/LibMath.sol"; import "./MixinConstants.sol"; + contract MixinWethFees is LibMath, MixinConstants |