Lawrence Forman 994908549d Asset-swapper aggregator utils (#2353)
* `@0x/asset-swapper`: Add ERC20Bridge aggregator library.

* `@0x/asset-swapper`: Finish off `aggregate.ts`.

* `@0x/types`: Add `OrderWithoutDomain` type.

* `@0x/asset-swapper`: Add testing infra for sampler/aggregator.

* `@0x/types`: Add `SignedOrderWithoutDomain` type.

* `@0x/asset-swapper`: Update aggregator to take and return orders with signatures.

* `@0x/asset-swapper`: Fix broken aggregator tests.

* `@0x/asset-swapper`: Pass the sampler contract into aggregator entry points.

* `@0x/contract-artifacts`: Add `IERC20BridgeSampler` artifact.

* `@0x/contract-wrappers`: Add `IERC20BridgeSampler` wrapper.

* `@0x/asset-swapper`: Address review comments.

* fixed testing

* refactored aggregate.ts and embeded into asset-swapper

* added adjusted rates for taker and maker fees

* remove PrunedSignedOrders

* updated contract-addresses and addressed some other todos

* streamlined logic

* patched in lawrences changes

* renamed aggregator utils and removed market_utils.ts

* added ack heartbeats

* fixed bug

* patches

* added dummy order things

* Dummy with valid sig

* Tweak gas price calculation to wei

* added test coverage and fixed bugs

* fixed migrations

* Fix CHANGELOGs and types export

* Deploy latest ERC20BridgeSampler on Mainnet

* `@0x/types` Revert CHANGELOG.

* `@0x/asset-swapper`: Address review comments.
`@0x/contract-addresses`: Make kyber lowercase.

* made protocol fee multiplier async

* `@0x/asset-swapper: Fix build errors and do some code cleanup.

* use assetDataUtils where possible
2019-12-16 12:35:58 -08:00

99 lines
3.9 KiB
TypeScript

import { constants as devConstants } from '@0x/contracts-test-utils';
import { AcceptedRejectedOrders, Orderbook } from '@0x/orderbook';
import { Web3ProviderEngine } from '@0x/subproviders';
import { APIOrder, AssetPairsItem, SignedOrder } from '@0x/types';
import { BigNumber } from '@0x/utils';
import * as TypeMoq from 'typemoq';
import { SwapQuoter } from '../../src/swap_quoter';
import { SignedOrderWithFillableAmounts } from '../../src/types';
import { ProtocolFeeUtils } from '../../src/utils/protocol_fee_utils';
const PROTOCOL_FEE_MULTIPLIER = 150000;
// tslint:disable: max-classes-per-file
class OrderbookClass extends Orderbook {
// tslint:disable-next-line:prefer-function-over-method
public async getOrdersAsync(_makerAssetData: string, _takerAssetData: string): Promise<APIOrder[]> {
return [];
}
// tslint:disable-next-line:prefer-function-over-method
public async getAvailableAssetDatasAsync(): Promise<AssetPairsItem[]> {
return [];
}
// tslint:disable-next-line:prefer-function-over-method
public async addOrdersAsync(_orders: SignedOrder[]): Promise<AcceptedRejectedOrders> {
return { accepted: [], rejected: [] };
}
}
export const orderbookMock = () => {
return TypeMoq.Mock.ofType(OrderbookClass, TypeMoq.MockBehavior.Strict);
};
export const mockAvailableAssetDatas = (
mockOrderbook: TypeMoq.IMock<OrderbookClass>,
availableAssetDatas: AssetPairsItem[],
) => {
mockOrderbook
.setup(async op => op.getAvailableAssetDatasAsync())
.returns(async () => availableAssetDatas)
.verifiable(TypeMoq.Times.once());
mockOrderbook
.setup(o => (o as any)._orderProvider)
.returns(() => undefined)
.verifiable(TypeMoq.Times.atLeast(0));
mockOrderbook
.setup(o => (o as any)._orderStore)
.returns(() => undefined)
.verifiable(TypeMoq.Times.atLeast(0));
};
const partiallyMockedSwapQuoter = (provider: Web3ProviderEngine, orderbook: Orderbook): TypeMoq.IMock<SwapQuoter> => {
const rawSwapQuoter = new SwapQuoter(provider, orderbook);
const mockedSwapQuoter = TypeMoq.Mock.ofInstance(rawSwapQuoter, TypeMoq.MockBehavior.Loose, false);
mockedSwapQuoter.callBase = true;
return mockedSwapQuoter;
};
class ProtocolFeeUtilsClass extends ProtocolFeeUtils {
// tslint:disable-next-line:prefer-function-over-method
public async getProtocolFeeMultiplierAsync(): Promise<BigNumber> {
return new BigNumber(PROTOCOL_FEE_MULTIPLIER);
}
// tslint:disable-next-line:prefer-function-over-method
public async getGasPriceEstimationOrThrowAsync(_shouldHardRefresh?: boolean): Promise<BigNumber> {
return new BigNumber(devConstants.DEFAULT_GAS_PRICE);
}
}
export const protocolFeeUtilsMock = (): TypeMoq.IMock<ProtocolFeeUtils> => {
const mockProtocolFeeUtils = TypeMoq.Mock.ofType(ProtocolFeeUtilsClass, TypeMoq.MockBehavior.Loose);
mockProtocolFeeUtils.callBase = true;
return mockProtocolFeeUtils;
};
const mockGetSignedOrdersWithFillableAmountsAsyncAsync = (
mockedSwapQuoter: TypeMoq.IMock<SwapQuoter>,
makerAssetData: string,
takerAssetData: string,
signedOrders: SignedOrderWithFillableAmounts[],
): void => {
mockedSwapQuoter
.setup(async a => a.getSignedOrdersWithFillableAmountsAsync(makerAssetData, takerAssetData))
.returns(async () => signedOrders)
.verifiable(TypeMoq.Times.once());
};
export const mockedSwapQuoterWithFillableAmounts = (
provider: Web3ProviderEngine,
orderbook: Orderbook,
makerAssetData: string,
takerAssetData: string,
signedOrders: SignedOrderWithFillableAmounts[],
): TypeMoq.IMock<SwapQuoter> => {
const mockedAssetQuoter = partiallyMockedSwapQuoter(provider, orderbook);
mockGetSignedOrdersWithFillableAmountsAsyncAsync(mockedAssetQuoter, makerAssetData, takerAssetData, signedOrders);
return mockedAssetQuoter;
};