slightly restructure contracts to fix bug in the WETH-fee case
This commit is contained in:
parent
7ff7e9d2e7
commit
1b8a9e16e2
@ -89,11 +89,13 @@ contract MixinExchangeWrapper is
|
|||||||
bytes[] memory signatures
|
bytes[] memory signatures
|
||||||
)
|
)
|
||||||
internal
|
internal
|
||||||
returns (FillResults memory totalFillResults)
|
returns (
|
||||||
|
FillResults memory totalFillResults,
|
||||||
|
uint256 wethSpentAmount,
|
||||||
|
uint256 makerAssetAcquiredAmount
|
||||||
|
)
|
||||||
{
|
{
|
||||||
uint256 ordersLength = orders.length;
|
uint256 ordersLength = orders.length;
|
||||||
// The remaining amount of WETH to sell
|
|
||||||
uint256 remainingTakerAssetFillAmount = wethSellAmount;
|
|
||||||
|
|
||||||
for (uint256 i = 0; i != ordersLength; i++) {
|
for (uint256 i = 0; i != ordersLength; i++) {
|
||||||
require(
|
require(
|
||||||
@ -101,34 +103,62 @@ contract MixinExchangeWrapper is
|
|||||||
"MAKER_ASSET_MISMATCH"
|
"MAKER_ASSET_MISMATCH"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// The remaining amount of WETH to sell
|
||||||
|
uint256 remainingTakerAssetFillAmount = _safeSub(
|
||||||
|
wethSellAmount,
|
||||||
|
wethSpentAmount
|
||||||
|
);
|
||||||
|
FillResults memory singleFillResults;
|
||||||
|
|
||||||
|
// Update amounts filled and the remaining amount of WETH to sell
|
||||||
|
if (orders[i].makerAssetData.equals(orders[i].takerFeeAssetData)) {
|
||||||
// Attempt to sell the remaining amount of WETH
|
// Attempt to sell the remaining amount of WETH
|
||||||
FillResults memory singleFillResults = _fillOrderNoThrow(
|
singleFillResults = _fillOrderNoThrow(
|
||||||
orders[i],
|
orders[i],
|
||||||
remainingTakerAssetFillAmount,
|
remainingTakerAssetFillAmount,
|
||||||
signatures[i]
|
signatures[i]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Update amounts filled and the remaining amount of WETH to sell
|
makerAssetAcquiredAmount = _safeAdd(
|
||||||
if (orders[i].makerAssetData.equals(orders[i].takerFeeAssetData)) {
|
makerAssetAcquiredAmount,
|
||||||
_addFillResultsDeductFees(totalFillResults, singleFillResults);
|
_safeSub(singleFillResults.makerAssetFilledAmount, singleFillResults.takerFeePaid)
|
||||||
} else {
|
|
||||||
_addFillResults(totalFillResults, singleFillResults);
|
|
||||||
remainingTakerAssetFillAmount = _safeSub(
|
|
||||||
remainingTakerAssetFillAmount,
|
|
||||||
singleFillResults.takerFeePaid
|
|
||||||
);
|
);
|
||||||
}
|
wethSpentAmount = _safeAdd(
|
||||||
remainingTakerAssetFillAmount = _safeSub(
|
wethSpentAmount,
|
||||||
remainingTakerAssetFillAmount,
|
|
||||||
singleFillResults.takerAssetFilledAmount
|
singleFillResults.takerAssetFilledAmount
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
// We first sell WETH as the takerAsset, then use it to pay the takerFee.
|
||||||
|
// This ensures that we reserve enough to pay the fee.
|
||||||
|
uint256 takerAssetFillAmount = _getPartialAmountCeil(
|
||||||
|
orders[i].takerAssetAmount,
|
||||||
|
_safeAdd(orders[i].takerAssetAmount, orders[i].takerFee),
|
||||||
|
remainingTakerAssetFillAmount
|
||||||
|
);
|
||||||
|
singleFillResults = _fillOrderNoThrow(
|
||||||
|
orders[i],
|
||||||
|
takerAssetFillAmount,
|
||||||
|
signatures[i]
|
||||||
|
);
|
||||||
|
|
||||||
|
wethSpentAmount = _safeAdd(
|
||||||
|
wethSpentAmount,
|
||||||
|
_safeAdd(singleFillResults.takerAssetFilledAmount, singleFillResults.takerFeePaid)
|
||||||
|
);
|
||||||
|
makerAssetAcquiredAmount = _safeAdd(
|
||||||
|
makerAssetAcquiredAmount,
|
||||||
|
singleFillResults.makerAssetFilledAmount
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_addFillResults(totalFillResults, singleFillResults);
|
||||||
|
|
||||||
// Stop execution if the entire amount of takerAsset has been sold
|
// Stop execution if the entire amount of takerAsset has been sold
|
||||||
if (totalFillResults.takerAssetFilledAmount >= wethSellAmount) {
|
if (wethSpentAmount >= wethSellAmount) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return totalFillResults;
|
return (totalFillResults, wethSpentAmount, makerAssetAcquiredAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Synchronously executes multiple fill orders in a single transaction until total amount is bought by taker.
|
/// @dev Synchronously executes multiple fill orders in a single transaction until total amount is bought by taker.
|
||||||
@ -144,10 +174,13 @@ contract MixinExchangeWrapper is
|
|||||||
bytes[] memory signatures
|
bytes[] memory signatures
|
||||||
)
|
)
|
||||||
internal
|
internal
|
||||||
returns (FillResults memory totalFillResults)
|
returns (
|
||||||
|
FillResults memory totalFillResults,
|
||||||
|
uint256 wethSpentAmount,
|
||||||
|
uint256 makerAssetAcquiredAmount
|
||||||
|
)
|
||||||
{
|
{
|
||||||
uint256 ordersLength = orders.length;
|
uint256 ordersLength = orders.length;
|
||||||
uint256 makerAssetFilledAmount = 0;
|
|
||||||
|
|
||||||
for (uint256 i = 0; i != ordersLength; i++) {
|
for (uint256 i = 0; i != ordersLength; i++) {
|
||||||
require(
|
require(
|
||||||
@ -156,7 +189,7 @@ contract MixinExchangeWrapper is
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Calculate the remaining amount of makerAsset to buy
|
// Calculate the remaining amount of makerAsset to buy
|
||||||
uint256 remainingMakerAssetFillAmount = _safeSub(makerAssetFillAmount, totalFillResults.makerAssetFilledAmount);
|
uint256 remainingMakerAssetFillAmount = _safeSub(makerAssetFillAmount, makerAssetAcquiredAmount);
|
||||||
|
|
||||||
// Convert the remaining amount of makerAsset to buy into remaining amount
|
// Convert the remaining amount of makerAsset to buy into remaining amount
|
||||||
// of takerAsset to sell, assuming entire amount can be sold in the current order.
|
// of takerAsset to sell, assuming entire amount can be sold in the current order.
|
||||||
@ -177,22 +210,36 @@ contract MixinExchangeWrapper is
|
|||||||
|
|
||||||
// Update amounts filled and fees paid by maker and taker
|
// Update amounts filled and fees paid by maker and taker
|
||||||
if (orders[i].makerAssetData.equals(orders[i].takerFeeAssetData)) {
|
if (orders[i].makerAssetData.equals(orders[i].takerFeeAssetData)) {
|
||||||
_addFillResultsDeductFees(totalFillResults, singleFillResults);
|
makerAssetAcquiredAmount = _safeAdd(
|
||||||
|
makerAssetAcquiredAmount,
|
||||||
|
_safeSub(singleFillResults.makerAssetFilledAmount, singleFillResults.takerFeePaid)
|
||||||
|
);
|
||||||
|
wethSpentAmount = _safeAdd(
|
||||||
|
wethSpentAmount,
|
||||||
|
singleFillResults.takerAssetFilledAmount
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
_addFillResults(totalFillResults, singleFillResults);
|
makerAssetAcquiredAmount = _safeAdd(
|
||||||
|
makerAssetAcquiredAmount,
|
||||||
|
_safeSub(singleFillResults.makerAssetFilledAmount, singleFillResults.takerFeePaid)
|
||||||
|
);
|
||||||
|
wethSpentAmount = _safeAdd(
|
||||||
|
wethSpentAmount,
|
||||||
|
singleFillResults.takerAssetFilledAmount
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
_addFillResults(totalFillResults, singleFillResults);
|
||||||
|
|
||||||
// Stop execution if the entire amount of makerAsset has been bought
|
// Stop execution if the entire amount of makerAsset has been bought
|
||||||
makerAssetFilledAmount = totalFillResults.makerAssetFilledAmount;
|
if (makerAssetAcquiredAmount >= makerAssetFillAmount) {
|
||||||
if (makerAssetFilledAmount >= makerAssetFillAmount) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
require(
|
require(
|
||||||
makerAssetFilledAmount >= makerAssetFillAmount,
|
makerAssetAcquiredAmount >= makerAssetFillAmount,
|
||||||
"COMPLETE_FILL_FAILED"
|
"COMPLETE_FILL_FAILED"
|
||||||
);
|
);
|
||||||
return totalFillResults;
|
return (totalFillResults, wethSpentAmount, makerAssetAcquiredAmount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,13 @@ contract MixinForwarderCore is
|
|||||||
|
|
||||||
// Market sell 95% of WETH.
|
// Market sell 95% of WETH.
|
||||||
// ZRX fees are payed with this contract's balance.
|
// ZRX fees are payed with this contract's balance.
|
||||||
orderFillResults = _marketSellWeth(
|
uint256 wethSpentAmount;
|
||||||
|
uint256 makerAssetAcquiredAmount;
|
||||||
|
(
|
||||||
|
orderFillResults,
|
||||||
|
wethSpentAmount,
|
||||||
|
makerAssetAcquiredAmount
|
||||||
|
) = _marketSellWeth(
|
||||||
orders,
|
orders,
|
||||||
wethSellAmount,
|
wethSellAmount,
|
||||||
signatures
|
signatures
|
||||||
@ -97,7 +103,7 @@ contract MixinForwarderCore is
|
|||||||
// Transfer feePercentage of total ETH spent on primary orders to feeRecipient.
|
// Transfer feePercentage of total ETH spent on primary orders to feeRecipient.
|
||||||
// Refund remaining ETH to msg.sender.
|
// Refund remaining ETH to msg.sender.
|
||||||
_transferEthFeeAndRefund(
|
_transferEthFeeAndRefund(
|
||||||
orderFillResults.takerAssetFilledAmount,
|
wethSpentAmount,
|
||||||
feePercentage,
|
feePercentage,
|
||||||
feeRecipient
|
feeRecipient
|
||||||
);
|
);
|
||||||
@ -105,7 +111,7 @@ contract MixinForwarderCore is
|
|||||||
// Transfer purchased assets to msg.sender.
|
// Transfer purchased assets to msg.sender.
|
||||||
_transferAssetToSender(
|
_transferAssetToSender(
|
||||||
orders[0].makerAssetData,
|
orders[0].makerAssetData,
|
||||||
orderFillResults.makerAssetFilledAmount
|
makerAssetAcquiredAmount
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +142,13 @@ contract MixinForwarderCore is
|
|||||||
|
|
||||||
// Attempt to purchase desired amount of makerAsset.
|
// Attempt to purchase desired amount of makerAsset.
|
||||||
// ZRX fees are payed with this contract's balance.
|
// ZRX fees are payed with this contract's balance.
|
||||||
orderFillResults = _marketBuyExactAmountWithWeth(
|
uint256 wethSpentAmount;
|
||||||
|
uint256 makerAssetAcquiredAmount;
|
||||||
|
(
|
||||||
|
orderFillResults,
|
||||||
|
wethSpentAmount,
|
||||||
|
makerAssetAcquiredAmount
|
||||||
|
) = _marketBuyExactAmountWithWeth(
|
||||||
orders,
|
orders,
|
||||||
makerAssetFillAmount,
|
makerAssetFillAmount,
|
||||||
signatures
|
signatures
|
||||||
@ -145,7 +157,7 @@ contract MixinForwarderCore is
|
|||||||
// Transfer feePercentage of total ETH spent on primary orders to feeRecipient.
|
// Transfer feePercentage of total ETH spent on primary orders to feeRecipient.
|
||||||
// Refund remaining ETH to msg.sender.
|
// Refund remaining ETH to msg.sender.
|
||||||
_transferEthFeeAndRefund(
|
_transferEthFeeAndRefund(
|
||||||
orderFillResults.takerAssetFilledAmount,
|
wethSpentAmount,
|
||||||
feePercentage,
|
feePercentage,
|
||||||
feeRecipient
|
feeRecipient
|
||||||
);
|
);
|
||||||
@ -153,7 +165,7 @@ contract MixinForwarderCore is
|
|||||||
// Transfer purchased assets to msg.sender.
|
// Transfer purchased assets to msg.sender.
|
||||||
_transferAssetToSender(
|
_transferAssetToSender(
|
||||||
orders[0].makerAssetData,
|
orders[0].makerAssetData,
|
||||||
orderFillResults.makerAssetFilledAmount
|
makerAssetAcquiredAmount
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,19 +402,4 @@ library LibFillResults {
|
|||||||
|
|
||||||
return matchedFillResults;
|
return matchedFillResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Adds properties of both FillResults instances.
|
|
||||||
/// Modifies the first FillResults instance specified.
|
|
||||||
/// @param totalFillResults Fill results instance that will be added onto.
|
|
||||||
/// @param singleFillResults Fill results instance that will be added to totalFillResults.
|
|
||||||
function _addFillResultsDeductFees(FillResults memory totalFillResults, FillResults memory singleFillResults)
|
|
||||||
internal
|
|
||||||
pure
|
|
||||||
{
|
|
||||||
totalFillResults.makerAssetFilledAmount = _safeAdd(totalFillResults.makerAssetFilledAmount, singleFillResults.makerAssetFilledAmount);
|
|
||||||
totalFillResults.takerAssetFilledAmount = _safeAdd(totalFillResults.takerAssetFilledAmount, singleFillResults.takerAssetFilledAmount);
|
|
||||||
|
|
||||||
// The fee amount must be deducted from the amount transfered back to sender.
|
|
||||||
totalFillResults.makerAssetFilledAmount = _safeSub(totalFillResults.makerAssetFilledAmount, singleFillResults.takerFeePaid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user