Skip to content
This repository has been archived by the owner on Jul 9, 2021. It is now read-only.

Commit

Permalink
@0x/asset-swapper: Use batchCall() version of the `ERC20BridgeSam…
Browse files Browse the repository at this point in the history
…pler` contract
  • Loading branch information
merklejerk committed Feb 8, 2020
1 parent 8ff2d03 commit 8ffceb0
Show file tree
Hide file tree
Showing 9 changed files with 1,082 additions and 487 deletions.
9 changes: 9 additions & 0 deletions packages/asset-swapper/CHANGELOG.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
[
{
"version": "4.2.0",
"changes": [
{
"note": "Use `batchCall()` version of the `ERC20BridgeSampler` contract",
"pr": 2477
}
]
},
{
"version": "4.1.1",
"changes": [
Expand Down
12 changes: 6 additions & 6 deletions packages/asset-swapper/src/swap_quoter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
} from './types';
import { assert } from './utils/assert';
import { calculateLiquidity } from './utils/calculate_liquidity';
import { MarketOperationUtils } from './utils/market_operation_utils';
import { DexOrderSampler, MarketOperationUtils } from './utils/market_operation_utils';
import { dummyOrderUtils } from './utils/market_operation_utils/dummy_order_utils';
import { orderPrunerUtils } from './utils/order_prune_utils';
import { OrderStateUtils } from './utils/order_state_utils';
Expand Down Expand Up @@ -162,12 +162,12 @@ export class SwapQuoter {
this._devUtilsContract = new DevUtilsContract(this._contractAddresses.devUtils, provider);
this._protocolFeeUtils = new ProtocolFeeUtils(constants.PROTOCOL_FEE_UTILS_POLLING_INTERVAL_IN_MS);
this._orderStateUtils = new OrderStateUtils(this._devUtilsContract);
const samplerContract = new IERC20BridgeSamplerContract(
this._contractAddresses.erc20BridgeSampler,
this.provider,
{ gas: samplerGasLimit },
const sampler = new DexOrderSampler(
new IERC20BridgeSamplerContract(this._contractAddresses.erc20BridgeSampler, this.provider, {
gas: samplerGasLimit,
}),
);
this._marketOperationUtils = new MarketOperationUtils(samplerContract, this._contractAddresses, {
this._marketOperationUtils = new MarketOperationUtils(sampler, this._contractAddresses, {
chainId,
exchangeAddress: this._contractAddresses.exchange,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,6 @@ import { ERC20BridgeSource, GetMarketOrdersOpts } from './types';

const INFINITE_TIMESTAMP_SEC = new BigNumber(2524604400);

/**
* Convert a source to a canonical address used by the sampler contract.
*/
const SOURCE_TO_ADDRESS: { [key: string]: string } = {
[ERC20BridgeSource.Eth2Dai]: '0x39755357759ce0d7f32dc8dc45414cca409ae24e',
[ERC20BridgeSource.Uniswap]: '0xc0a47dfe034b400b47bdad5fecda2621de6c4d95',
[ERC20BridgeSource.Kyber]: '0x818e6fecd516ecc3849daf6845e3ec868087b755',
};

/**
* Valid sources for market sell.
*/
Expand All @@ -36,7 +27,6 @@ export const DEFAULT_GET_MARKET_ORDERS_OPTS: GetMarketOrdersOpts = {

export const constants = {
INFINITE_TIMESTAMP_SEC,
SOURCE_TO_ADDRESS,
SELL_SOURCES,
BUY_SOURCES,
DEFAULT_GET_MARKET_ORDERS_OPTS,
Expand Down
62 changes: 38 additions & 24 deletions packages/asset-swapper/src/utils/market_operation_utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { ContractAddresses } from '@0x/contract-addresses';
import { IERC20BridgeSamplerContract } from '@0x/contract-wrappers';
import { assetDataUtils, ERC20AssetData, orderCalculationUtils } from '@0x/order-utils';
import { SignedOrder } from '@0x/types';
import { BigNumber } from '@0x/utils';
Expand All @@ -11,7 +10,7 @@ import { fillableAmountsUtils } from '../fillable_amounts_utils';
import { constants as marketOperationUtilConstants } from './constants';
import { CreateOrderUtils } from './create_order';
import { comparePathOutputs, FillsOptimizer, getPathOutput } from './fill_optimizer';
import { DexOrderSampler } from './sampler';
import { DexOrderSampler, getSampleAmounts } from './sampler';
import {
AggregationError,
CollapsedFill,
Expand All @@ -27,22 +26,20 @@ import {
OrderDomain,
} from './types';

export { DexOrderSampler } from './sampler';

const { ZERO_AMOUNT } = constants;
const { BUY_SOURCES, DEFAULT_GET_MARKET_ORDERS_OPTS, ERC20_PROXY_ID, SELL_SOURCES } = marketOperationUtilConstants;

export class MarketOperationUtils {
private readonly _dexSampler: DexOrderSampler;
private readonly _createOrderUtils: CreateOrderUtils;
private readonly _orderDomain: OrderDomain;

constructor(
samplerContract: IERC20BridgeSamplerContract,
private readonly _sampler: DexOrderSampler,
contractAddresses: ContractAddresses,
orderDomain: OrderDomain,
private readonly _orderDomain: OrderDomain,
) {
this._dexSampler = new DexOrderSampler(samplerContract);
this._createOrderUtils = new CreateOrderUtils(contractAddresses);
this._orderDomain = orderDomain;
}

/**
Expand All @@ -65,10 +62,15 @@ export class MarketOperationUtils {
...DEFAULT_GET_MARKET_ORDERS_OPTS,
...opts,
};
const [fillableAmounts, dexQuotes] = await this._dexSampler.getFillableAmountsAndSampleMarketSellAsync(
nativeOrders,
DexOrderSampler.getSampleAmounts(takerAmount, _opts.numSamples, _opts.sampleDistributionBase),
difference(SELL_SOURCES, _opts.excludedSources),
const [makerToken, takerToken] = getOrderTokens(nativeOrders[0]);
const [fillableAmounts, dexQuotes] = await this._sampler.executeAsync(
DexOrderSampler.ops.getOrderFillableTakerAmounts(nativeOrders),
DexOrderSampler.ops.getSellQuotes(
difference(SELL_SOURCES, _opts.excludedSources),
makerToken,
takerToken,
getSampleAmounts(takerAmount, _opts.numSamples, _opts.sampleDistributionBase),
),
);
const nativeOrdersWithFillableAmounts = createSignedOrdersWithFillableAmounts(
nativeOrders,
Expand Down Expand Up @@ -134,11 +136,15 @@ export class MarketOperationUtils {
...DEFAULT_GET_MARKET_ORDERS_OPTS,
...opts,
};

const [fillableAmounts, dexQuotes] = await this._dexSampler.getFillableAmountsAndSampleMarketBuyAsync(
nativeOrders,
DexOrderSampler.getSampleAmounts(makerAmount, _opts.numSamples, _opts.sampleDistributionBase),
difference(BUY_SOURCES, _opts.excludedSources),
const [makerToken, takerToken] = getOrderTokens(nativeOrders[0]);
const [fillableAmounts, dexQuotes] = await this._sampler.executeAsync(
DexOrderSampler.ops.getOrderFillableMakerAmounts(nativeOrders),
DexOrderSampler.ops.getBuyQuotes(
difference(BUY_SOURCES, _opts.excludedSources),
makerToken,
takerToken,
getSampleAmounts(makerAmount, _opts.numSamples, _opts.sampleDistributionBase),
),
);
const signedOrderWithFillableAmounts = this._createBuyOrdersPathFromSamplerResultIfExists(
nativeOrders,
Expand Down Expand Up @@ -174,17 +180,25 @@ export class MarketOperationUtils {
...opts,
};

const batchSampleResults = await this._dexSampler.getBatchFillableAmountsAndSampleMarketBuyAsync(
batchNativeOrders,
makerAmounts.map(makerAmount => DexOrderSampler.getSampleAmounts(makerAmount, _opts.numSamples)),
difference(BUY_SOURCES, _opts.excludedSources),
);
return batchSampleResults.map(([fillableAmounts, dexQuotes], i) =>
const sources = difference(BUY_SOURCES, _opts.excludedSources);
const ops = [
...batchNativeOrders.map(orders => DexOrderSampler.ops.getOrderFillableMakerAmounts(orders)),
...batchNativeOrders.map((orders, i) =>
DexOrderSampler.ops.getBuyQuotes(sources, getOrderTokens(orders[0])[0], getOrderTokens(orders[0])[1], [
makerAmounts[i],
]),
),
];
const executeResults = await this._sampler.executeBatchAsync(ops);
const batchFillableAmounts = executeResults.slice(0, batchNativeOrders.length) as BigNumber[][];
const batchDexQuotes = executeResults.slice(batchNativeOrders.length) as DexSample[][][];

return batchFillableAmounts.map((fillableAmounts, i) =>
this._createBuyOrdersPathFromSamplerResultIfExists(
batchNativeOrders[i],
makerAmounts[i],
fillableAmounts,
dexQuotes,
batchDexQuotes[i],
_opts,
),
);
Expand Down
Loading

0 comments on commit 8ffceb0

Please sign in to comment.