diff options
author | Amir Bandeali <abandeali1@gmail.com> | 2018-07-18 02:32:44 +0800 |
---|---|---|
committer | Amir Bandeali <abandeali1@gmail.com> | 2018-07-23 23:00:23 +0800 |
commit | 799ff2a5c392383c8b245ae53057593acc2534ce (patch) | |
tree | 5899d3843420c36e0e0c750f3ac47a7aab3b1e91 /packages/contracts/src/2.0.0/forwarder/MixinForwarderCore.sol | |
parent | ec5f768f9b9a333fc577e0885cd15f261997a367 (diff) | |
download | dexon-sol-tools-799ff2a5c392383c8b245ae53057593acc2534ce.tar dexon-sol-tools-799ff2a5c392383c8b245ae53057593acc2534ce.tar.gz dexon-sol-tools-799ff2a5c392383c8b245ae53057593acc2534ce.tar.bz2 dexon-sol-tools-799ff2a5c392383c8b245ae53057593acc2534ce.tar.lz dexon-sol-tools-799ff2a5c392383c8b245ae53057593acc2534ce.tar.xz dexon-sol-tools-799ff2a5c392383c8b245ae53057593acc2534ce.tar.zst dexon-sol-tools-799ff2a5c392383c8b245ae53057593acc2534ce.zip |
Fix rounding error issues, use different logic when makerAsset is ZRX
Diffstat (limited to 'packages/contracts/src/2.0.0/forwarder/MixinForwarderCore.sol')
-rw-r--r-- | packages/contracts/src/2.0.0/forwarder/MixinForwarderCore.sol | 121 |
1 files changed, 86 insertions, 35 deletions
diff --git a/packages/contracts/src/2.0.0/forwarder/MixinForwarderCore.sol b/packages/contracts/src/2.0.0/forwarder/MixinForwarderCore.sol index 19b1c357b..9dc203373 100644 --- a/packages/contracts/src/2.0.0/forwarder/MixinForwarderCore.sol +++ b/packages/contracts/src/2.0.0/forwarder/MixinForwarderCore.sol @@ -23,6 +23,7 @@ import "./mixins/MWeth.sol"; import "./mixins/MAssets.sol"; import "./mixins/MConstants.sol"; import "./mixins/MForwarderCore.sol"; +import "../utils/LibBytes/LibBytes.sol"; import "../protocol/Exchange/libs/LibOrder.sol"; import "../protocol/Exchange/libs/LibFillResults.sol"; import "../protocol/Exchange/libs/LibMath.sol"; @@ -37,6 +38,8 @@ contract MixinForwarderCore is MForwarderCore { + using LibBytes for bytes; + /// @dev Constructor approves ERC20 proxy to transfer ZRX and WETH on this contract's behalf. constructor () public @@ -74,24 +77,54 @@ contract MixinForwarderCore is FillResults memory feeOrderFillResults ) { - // Convert ETH to WETH. - // 5% of WETH is reserved for filling feeOrders and paying feeRecipient. - uint256 wethAvailable = convertEthToWeth(); - - // Attempt to sell 95% of WETH. - // ZRX fees are payed with this contract's balance. - orderFillResults = marketSellWeth( - orders, - wethAvailable, - signatures + require( + orders.length > 0, + "INVALID_ORDERS_LENGTH" ); - // Buy back all ZRX spent on fees. - feeOrderFillResults = marketBuyZrx( - feeOrders, - orderFillResults.takerFeePaid, - feeSignatures - ); + // Convert ETH to WETH. + convertEthToWeth(); + + uint256 makerAssetAmountPurchased; + uint256 wethAvailable; + if (orders[0].makerAssetData.equals(ZRX_ASSET_DATA)) { + // Calculate amount of WETH that won't be spent on ETH fees. + wethAvailable = getPartialAmount( + PERCENTAGE_DENOMINATOR, + safeAdd(PERCENTAGE_DENOMINATOR, feePercentage), + msg.value + ); + // Market sell available WETH. + // ZRX fees are paid with this contract's balance. + orderFillResults = marketSellWeth( + orders, + wethAvailable, + signatures + ); + // The fee amount must be deducted from the amount transfered back to sender. + makerAssetAmountPurchased = safeSub(orderFillResults.makerAssetFilledAmount, orderFillResults.takerFeePaid); + } else { + // 5% of WETH is reserved for filling feeOrders and paying feeRecipient. + wethAvailable = getPartialAmount( + MAX_WETH_FILL_PERCENTAGE, + PERCENTAGE_DENOMINATOR, + msg.value + ); + // Market sell 95% of WETH. + // ZRX fees are payed with this contract's balance. + orderFillResults = marketSellWeth( + orders, + wethAvailable, + signatures + ); + // Buy back all ZRX spent on fees. + feeOrderFillResults = marketBuyZrx( + feeOrders, + orderFillResults.takerFeePaid, + feeSignatures + ); + makerAssetAmountPurchased = orderFillResults.makerAssetFilledAmount; + } // Ensure that no extra WETH owned by this contract has been sold. uint256 totalWethSold = safeAdd(orderFillResults.takerAssetFilledAmount, feeOrderFillResults.takerAssetFilledAmount); @@ -110,7 +143,7 @@ contract MixinForwarderCore is ); // Transfer purchased assets to msg.sender. - transferPurchasedAssetToSender(orders[0].makerAssetData, orderFillResults.makerAssetFilledAmount); + transferPurchasedAssetToSender(orders[0].makerAssetData, makerAssetAmountPurchased); } /// @dev Attempt to purchase makerAssetFillAmount of makerAsset by selling ETH provided with transaction. @@ -140,23 +173,41 @@ contract MixinForwarderCore is FillResults memory feeOrderFillResults ) { + require( + orders.length > 0, + "INVALID_ORDERS_LENGTH" + ); + // Convert ETH to WETH. convertEthToWeth(); - // Attemp to purchase desired amount of makerAsset. - // ZRX fees are payed with this contract's balance. - orderFillResults = marketBuyAsset( - orders, - makerAssetFillAmount, - signatures - ); - - // Buy back all ZRX spent on fees. - feeOrderFillResults = marketBuyZrx( - feeOrders, - orderFillResults.takerFeePaid, - feeSignatures - ); + uint256 makerAssetAmountPurchased; + if (orders[0].makerAssetData.equals(ZRX_ASSET_DATA)) { + // If the makerAsset is ZRX, it is not necessary to pay fees out of this + // contracts's ZRX balance because fees are factored into the price of the order. + orderFillResults = marketBuyZrx( + orders, + makerAssetFillAmount, + signatures + ); + // The fee amount must be deducted from the amount transfered back to sender. + makerAssetAmountPurchased = safeSub(orderFillResults.makerAssetFilledAmount, orderFillResults.takerFeePaid); + } else { + // Attemp to purchase desired amount of makerAsset. + // ZRX fees are payed with this contract's balance. + orderFillResults = marketBuyAsset( + orders, + makerAssetFillAmount, + signatures + ); + // Buy back all ZRX spent on fees. + feeOrderFillResults = marketBuyZrx( + feeOrders, + orderFillResults.takerFeePaid, + feeSignatures + ); + makerAssetAmountPurchased = orderFillResults.makerAssetFilledAmount; + } // Ensure that no extra WETH owned by this contract has been sold. uint256 totalWethSold = safeAdd(orderFillResults.takerAssetFilledAmount, feeOrderFillResults.takerAssetFilledAmount); @@ -175,7 +226,7 @@ contract MixinForwarderCore is ); // Transfer purchased assets to msg.sender. - transferPurchasedAssetToSender(orders[0].makerAssetData, orderFillResults.makerAssetFilledAmount); + transferPurchasedAssetToSender(orders[0].makerAssetData, makerAssetAmountPurchased); } /// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset. @@ -280,7 +331,7 @@ contract MixinForwarderCore is // Attempt to sell the remaining amount of WETH. FillResults memory singleFillResult = EXCHANGE.fillOrderNoThrow( orders[i], - remainingWethSellAmount, + safeAdd(remainingWethSellAmount, 1), signatures[i] ); @@ -289,14 +340,14 @@ contract MixinForwarderCore is zrxPurchased = safeSub(totalFillResults.makerAssetFilledAmount, totalFillResults.takerFeePaid); // Stop execution if the entire amount of ZRX has been bought. - if (zrxPurchased == zrxBuyAmount) { + if (zrxPurchased >= zrxBuyAmount) { break; } } // Ensure that all ZRX spent while filling primary orders has been repurchased. require( - zrxPurchased == zrxBuyAmount, + zrxPurchased >= zrxBuyAmount, "COMPLETE_FILL_FAILED" ); } |