@0x/contracts-exchange: Avoid redundant trasfer in fillOrder() when maker/taker is the same as feeRecipient and the assets match.
`@0x/contracts-exchange`: Swap fill order in `fillOrder()` from maker -> taker to taker -> maker first
This commit is contained in:
committed by
Amir Bandeali
parent
9cc8933eec
commit
cd08c3e8fa
@@ -37,6 +37,14 @@
|
||||
{
|
||||
"note": "Incorporate Multi-asset and ERC1155 tests into `fillOrder` and `matchOrders` tests",
|
||||
"pr": 1819
|
||||
},
|
||||
{
|
||||
"note": "Swap fill order from maker -> taker to taker -> maker",
|
||||
"pr": 1819
|
||||
},
|
||||
{
|
||||
"note": "Avoid redundant transfer in `fillOrder` when maker/taker is the same as feeRecipient and assets are the same",
|
||||
"pr": 1819
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -611,33 +611,67 @@ contract MixinExchangeCore is
|
||||
)
|
||||
private
|
||||
{
|
||||
_dispatchTransferFrom(
|
||||
orderHash,
|
||||
order.makerAssetData,
|
||||
order.makerAddress,
|
||||
takerAddress,
|
||||
fillResults.makerAssetFilledAmount
|
||||
);
|
||||
_dispatchTransferFrom(
|
||||
orderHash,
|
||||
order.takerAssetData,
|
||||
takerAddress,
|
||||
order.makerAddress,
|
||||
fillResults.takerAssetFilledAmount
|
||||
);
|
||||
_dispatchTransferFrom(
|
||||
orderHash,
|
||||
order.makerFeeAssetData,
|
||||
order.makerAddress,
|
||||
order.feeRecipientAddress,
|
||||
fillResults.makerFeePaid
|
||||
);
|
||||
_dispatchTransferFrom(
|
||||
orderHash,
|
||||
order.takerFeeAssetData,
|
||||
takerAddress,
|
||||
order.feeRecipientAddress,
|
||||
fillResults.takerFeePaid
|
||||
);
|
||||
if (
|
||||
order.makerAddress == order.feeRecipientAddress &&
|
||||
order.makerFeeAssetData.equals(order.takerAssetData)
|
||||
) {
|
||||
// Maker is fee recipient and the maker fee asset is the same as the taker asset.
|
||||
// We can transfer the taker asset and maker fees in one go.
|
||||
_dispatchTransferFrom(
|
||||
orderHash,
|
||||
order.takerAssetData,
|
||||
takerAddress,
|
||||
order.makerAddress,
|
||||
_safeAdd(fillResults.takerAssetFilledAmount, fillResults.makerFeePaid)
|
||||
);
|
||||
} else {
|
||||
// Transfer taker -> maker
|
||||
_dispatchTransferFrom(
|
||||
orderHash,
|
||||
order.takerAssetData,
|
||||
takerAddress,
|
||||
order.makerAddress,
|
||||
fillResults.takerAssetFilledAmount
|
||||
);
|
||||
// Transfer maker fee -> feeRecipient
|
||||
_dispatchTransferFrom(
|
||||
orderHash,
|
||||
order.makerFeeAssetData,
|
||||
order.makerAddress,
|
||||
order.feeRecipientAddress,
|
||||
fillResults.makerFeePaid
|
||||
);
|
||||
}
|
||||
if (
|
||||
takerAddress == order.feeRecipientAddress &&
|
||||
order.takerFeeAssetData.equals(order.makerAssetData)
|
||||
) {
|
||||
// Taker is fee recipient and the taker fee asset is the same as the maker asset.
|
||||
// We can transfer the maker asset and taker fees in one go.
|
||||
_dispatchTransferFrom(
|
||||
orderHash,
|
||||
order.makerAssetData,
|
||||
order.makerAddress,
|
||||
takerAddress,
|
||||
_safeAdd(fillResults.makerAssetFilledAmount, fillResults.takerFeePaid)
|
||||
);
|
||||
} else {
|
||||
// Transfer maker -> taker
|
||||
_dispatchTransferFrom(
|
||||
orderHash,
|
||||
order.makerAssetData,
|
||||
order.makerAddress,
|
||||
takerAddress,
|
||||
fillResults.makerAssetFilledAmount
|
||||
);
|
||||
// Transfer taker fee -> feeRecipient
|
||||
_dispatchTransferFrom(
|
||||
orderHash,
|
||||
order.takerFeeAssetData,
|
||||
takerAddress,
|
||||
order.feeRecipientAddress,
|
||||
fillResults.takerFeePaid
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ const defaultFillScenario = {
|
||||
},
|
||||
};
|
||||
|
||||
describe('FillOrder Tests', () => {
|
||||
describe.only('FillOrder Tests', () => {
|
||||
let fillOrderCombinatorialUtils: FillOrderCombinatorialUtils;
|
||||
|
||||
before(async () => {
|
||||
|
||||
@@ -11,14 +11,7 @@ import {
|
||||
import { ERC1155Contract as ERC1155TokenContract, Erc1155Wrapper as ERC1155Wrapper } from '@0x/contracts-erc1155';
|
||||
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
|
||||
import { DummyERC721TokenContract } from '@0x/contracts-erc721';
|
||||
import {
|
||||
chaiSetup,
|
||||
constants,
|
||||
OrderFactory,
|
||||
provider,
|
||||
txDefaults,
|
||||
web3Wrapper,
|
||||
} from '@0x/contracts-test-utils';
|
||||
import { chaiSetup, constants, OrderFactory, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils';
|
||||
import { BlockchainLifecycle } from '@0x/dev-utils';
|
||||
import { assetDataUtils, ExchangeRevertErrors, orderHashUtils } from '@0x/order-utils';
|
||||
import { OrderStatus, RevertReason } from '@0x/types';
|
||||
|
||||
@@ -71,45 +71,69 @@ export class FillOrderSimulator {
|
||||
);
|
||||
|
||||
try {
|
||||
// Maker -> Taker
|
||||
await this._transferSimulator.transferFromAsync(
|
||||
order.makerAssetData,
|
||||
order.makerAddress,
|
||||
takerAddress,
|
||||
makerAssetFillAmount,
|
||||
TradeSide.Maker,
|
||||
TransferType.Trade,
|
||||
);
|
||||
// Taker -> Maker
|
||||
await this._transferSimulator.transferFromAsync(
|
||||
order.takerAssetData,
|
||||
takerAddress,
|
||||
order.makerAddress,
|
||||
finalTakerAssetFillAmount,
|
||||
TradeSide.Taker,
|
||||
TransferType.Trade,
|
||||
);
|
||||
// Maker fee -> fee recipient
|
||||
if (makerFeePaid.isGreaterThan(0)) {
|
||||
if (order.makerAddress === order.feeRecipientAddress && order.takerAssetData === order.makerFeeAssetData) {
|
||||
// Transfer combined taker assets and maker fees.
|
||||
await this._transferSimulator.transferFromAsync(
|
||||
order.makerFeeAssetData,
|
||||
order.makerAddress,
|
||||
order.feeRecipientAddress,
|
||||
makerFeePaid,
|
||||
TradeSide.Maker,
|
||||
TransferType.Fee,
|
||||
);
|
||||
}
|
||||
// Taker fee -> fee recipient
|
||||
if (takerFeePaid.isGreaterThan(0)) {
|
||||
await this._transferSimulator.transferFromAsync(
|
||||
order.takerFeeAssetData,
|
||||
order.takerAssetData,
|
||||
takerAddress,
|
||||
order.feeRecipientAddress,
|
||||
takerFeePaid,
|
||||
order.makerAddress,
|
||||
finalTakerAssetFillAmount.plus(makerFeePaid),
|
||||
TradeSide.Taker,
|
||||
TransferType.Fee,
|
||||
TransferType.Trade,
|
||||
);
|
||||
} else {
|
||||
// Taker -> Maker
|
||||
await this._transferSimulator.transferFromAsync(
|
||||
order.takerAssetData,
|
||||
takerAddress,
|
||||
order.makerAddress,
|
||||
finalTakerAssetFillAmount,
|
||||
TradeSide.Taker,
|
||||
TransferType.Trade,
|
||||
);
|
||||
// Maker fee -> fee recipient
|
||||
if (makerFeePaid.isGreaterThan(0)) {
|
||||
await this._transferSimulator.transferFromAsync(
|
||||
order.makerFeeAssetData,
|
||||
order.makerAddress,
|
||||
order.feeRecipientAddress,
|
||||
makerFeePaid,
|
||||
TradeSide.Maker,
|
||||
TransferType.Fee,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (takerAddress === order.feeRecipientAddress && order.makerAssetData === order.takerFeeAssetData) {
|
||||
// Transfer combined maker assets and taker fees.
|
||||
await this._transferSimulator.transferFromAsync(
|
||||
order.makerAssetData,
|
||||
order.makerAddress,
|
||||
takerAddress,
|
||||
makerAssetFillAmount.plus(takerFeePaid),
|
||||
TradeSide.Maker,
|
||||
TransferType.Trade,
|
||||
);
|
||||
} else {
|
||||
// Maker -> Taker
|
||||
await this._transferSimulator.transferFromAsync(
|
||||
order.makerAssetData,
|
||||
order.makerAddress,
|
||||
takerAddress,
|
||||
makerAssetFillAmount,
|
||||
TradeSide.Maker,
|
||||
TransferType.Trade,
|
||||
);
|
||||
// Taker fee -> fee recipient
|
||||
if (takerFeePaid.isGreaterThan(0)) {
|
||||
await this._transferSimulator.transferFromAsync(
|
||||
order.takerFeeAssetData,
|
||||
takerAddress,
|
||||
order.feeRecipientAddress,
|
||||
takerFeePaid,
|
||||
TradeSide.Taker,
|
||||
TransferType.Fee,
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
throw new Error(FillOrderError.TransferFailed);
|
||||
|
||||
Reference in New Issue
Block a user