Compare commits

..

4 Commits

Author SHA1 Message Date
Github Actions
76dda9eeda Publish
- @0x/contracts-integrations@2.7.31
 - @0x/asset-swapper@6.5.0
2021-04-08 20:27:04 +00:00
Github Actions
a9b84a92ac Updated CHANGELOGS & MD docs 2021-04-08 20:26:57 +00:00
mzhu25
0f7e881899 Add default liquidity provider registry and allow gas costs to be a function of tokens (#196) 2021-04-08 11:09:32 -07:00
mzhu25
6045f777ab Add Kyber DMM as a liquidity source (#194)
* Add Kyber DMM as a liquidity source

* update changelog
2021-04-07 10:08:19 -07:00
11 changed files with 132 additions and 43 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "@0x/contracts-integrations", "name": "@0x/contracts-integrations",
"version": "2.7.30", "version": "2.7.31",
"private": true, "private": true,
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
@@ -93,7 +93,7 @@
"typescript": "4.2.2" "typescript": "4.2.2"
}, },
"dependencies": { "dependencies": {
"@0x/asset-swapper": "^6.4.0", "@0x/asset-swapper": "^6.5.0",
"@0x/base-contract": "^6.2.18", "@0x/base-contract": "^6.2.18",
"@0x/contracts-asset-proxy": "^3.7.9", "@0x/contracts-asset-proxy": "^3.7.9",
"@0x/contracts-erc1155": "^2.1.27", "@0x/contracts-erc1155": "^2.1.27",

View File

@@ -1,4 +1,18 @@
[ [
{
"version": "6.5.0",
"changes": [
{
"note": "Add Kyber DMM to Ethereum mainnet",
"pr": 194
},
{
"note": "Add default LiquidityProvider registry and allow LiquidityProvider gasCost to be a function of tokens",
"pr": 196
}
],
"timestamp": 1617913615
},
{ {
"version": "6.4.0", "version": "6.4.0",
"changes": [ "changes": [

View File

@@ -5,6 +5,11 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG CHANGELOG
## v6.5.0 - _April 8, 2021_
* Add Kyber DMM to Ethereum mainnet (#194)
* Add default LiquidityProvider registry and allow LiquidityProvider gasCost to be a function of tokens (#196)
## v6.4.0 - _April 1, 2021_ ## v6.4.0 - _April 1, 2021_
* Use SOURCE_FLAGS.rfqOrder in comparisonPrice (#177) * Use SOURCE_FLAGS.rfqOrder in comparisonPrice (#177)

View File

@@ -1,6 +1,6 @@
{ {
"name": "@0x/asset-swapper", "name": "@0x/asset-swapper",
"version": "6.4.0", "version": "6.5.0",
"engines": { "engines": {
"node": ">=6.12" "node": ">=6.12"
}, },

View File

@@ -7,6 +7,7 @@ import {
CRYPTO_COM_ROUTER_BY_CHAIN_ID, CRYPTO_COM_ROUTER_BY_CHAIN_ID,
ELLIPSIS_BSC_INFOS, ELLIPSIS_BSC_INFOS,
KYBER_BRIDGED_LIQUIDITY_PREFIX, KYBER_BRIDGED_LIQUIDITY_PREFIX,
KYBER_DMM_ROUTER_BY_CHAIN_ID,
MAINNET_CURVE_INFOS, MAINNET_CURVE_INFOS,
MAINNET_SNOWSWAP_INFOS, MAINNET_SNOWSWAP_INFOS,
MAINNET_SWERVE_INFOS, MAINNET_SWERVE_INFOS,
@@ -176,7 +177,8 @@ export function uniswapV2LikeRouterAddress(
| ERC20BridgeSource.SushiSwap | ERC20BridgeSource.SushiSwap
| ERC20BridgeSource.CryptoCom | ERC20BridgeSource.CryptoCom
| ERC20BridgeSource.PancakeSwap | ERC20BridgeSource.PancakeSwap
| ERC20BridgeSource.BakerySwap, | ERC20BridgeSource.BakerySwap
| ERC20BridgeSource.KyberDmm,
): string { ): string {
switch (source) { switch (source) {
case ERC20BridgeSource.UniswapV2: case ERC20BridgeSource.UniswapV2:
@@ -189,6 +191,8 @@ export function uniswapV2LikeRouterAddress(
return PANCAKESWAP_ROUTER_BY_CHAIN_ID[chainId]; return PANCAKESWAP_ROUTER_BY_CHAIN_ID[chainId];
case ERC20BridgeSource.BakerySwap: case ERC20BridgeSource.BakerySwap:
return BAKERYSWAP_ROUTER_BY_CHAIN_ID[chainId]; return BAKERYSWAP_ROUTER_BY_CHAIN_ID[chainId];
case ERC20BridgeSource.KyberDmm:
return KYBER_DMM_ROUTER_BY_CHAIN_ID[chainId];
default: default:
throw new Error(`Unknown UniswapV2 like source ${source}`); throw new Error(`Unknown UniswapV2 like source ${source}`);
} }

View File

@@ -82,6 +82,7 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.CryptoCom, ERC20BridgeSource.CryptoCom,
ERC20BridgeSource.Linkswap, ERC20BridgeSource.Linkswap,
ERC20BridgeSource.MakerPsm, ERC20BridgeSource.MakerPsm,
ERC20BridgeSource.KyberDmm,
]), ]),
[ChainId.Ropsten]: new SourceFilters([ERC20BridgeSource.Native]), [ChainId.Ropsten]: new SourceFilters([ERC20BridgeSource.Native]),
[ChainId.Rinkeby]: new SourceFilters([ERC20BridgeSource.Native]), [ChainId.Rinkeby]: new SourceFilters([ERC20BridgeSource.Native]),
@@ -132,6 +133,7 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.CryptoCom, ERC20BridgeSource.CryptoCom,
ERC20BridgeSource.Linkswap, ERC20BridgeSource.Linkswap,
ERC20BridgeSource.MakerPsm, ERC20BridgeSource.MakerPsm,
ERC20BridgeSource.KyberDmm,
]), ]),
[ChainId.Ropsten]: new SourceFilters([ERC20BridgeSource.Native]), [ChainId.Ropsten]: new SourceFilters([ERC20BridgeSource.Native]),
[ChainId.Rinkeby]: new SourceFilters([ERC20BridgeSource.Native]), [ChainId.Rinkeby]: new SourceFilters([ERC20BridgeSource.Native]),
@@ -163,7 +165,7 @@ export const PROTOCOL_FEE_MULTIPLIER = new BigNumber(70000);
*/ */
export const FEE_QUOTE_SOURCES_BY_CHAIN_ID = valueByChainId<ERC20BridgeSource[]>( export const FEE_QUOTE_SOURCES_BY_CHAIN_ID = valueByChainId<ERC20BridgeSource[]>(
{ {
[ChainId.Mainnet]: [ERC20BridgeSource.Uniswap, ERC20BridgeSource.UniswapV2], [ChainId.Mainnet]: [ERC20BridgeSource.UniswapV2, ERC20BridgeSource.SushiSwap],
[ChainId.BSC]: [ERC20BridgeSource.PancakeSwap, ERC20BridgeSource.Mooniswap, ERC20BridgeSource.SushiSwap], [ChainId.BSC]: [ERC20BridgeSource.PancakeSwap, ERC20BridgeSource.Mooniswap, ERC20BridgeSource.SushiSwap],
}, },
[], [],
@@ -234,6 +236,9 @@ export const TOKENS = {
sEUR: '0xd71ecff9342a5ced620049e616c5035f1db98620', sEUR: '0xd71ecff9342a5ced620049e616c5035f1db98620',
sETH: '0x5e74c9036fb86bd7ecdcb084a0673efc32ea31cb', sETH: '0x5e74c9036fb86bd7ecdcb084a0673efc32ea31cb',
LINK: '0x514910771af9ca656af840dff83e8264ecf986ca', LINK: '0x514910771af9ca656af840dff83e8264ecf986ca',
MANA: '0x0f5d2fb29fb7d3cfee444a200298f468908cc942',
KNC: '0xdd974d5c2e2928dea5f71b9825b8b646686bd200',
AAVE: '0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9',
// Mirror Protocol // Mirror Protocol
UST: '0xa47c8bf37f92abed4a126bda807a7b7498661acd', UST: '0xa47c8bf37f92abed4a126bda807a7b7498661acd',
MIR: '0x09a3ecafa817268f77be1283176b946c4ff2e608', MIR: '0x09a3ecafa817268f77be1283176b946c4ff2e608',
@@ -610,7 +615,30 @@ export const KYBER_CONFIG_BY_CHAIN_ID = valueByChainId<KyberSamplerOpts>(
}, },
); );
export const LIQUIDITY_PROVIDER_REGISTRY: LiquidityProviderRegistry = {}; export const LIQUIDITY_PROVIDER_REGISTRY_BY_CHAIN_ID = valueByChainId<LiquidityProviderRegistry>(
{
[ChainId.Mainnet]: {
['0x1d0d407c5af8c86f0a6494de86e56ae21e46a951']: {
tokens: [
TOKENS.WETH,
TOKENS.USDC,
TOKENS.USDT,
TOKENS.WBTC,
TOKENS.PAX,
TOKENS.LINK,
TOKENS.KNC,
TOKENS.MANA,
TOKENS.DAI,
TOKENS.BUSD,
TOKENS.AAVE,
],
gasCost: (takerToken: string, makerToken: string) =>
[takerToken, makerToken].includes(TOKENS.WETH) ? 160e3 : 280e3,
},
},
},
{},
);
export const UNISWAPV1_ROUTER_BY_CHAIN_ID = valueByChainId<string>( export const UNISWAPV1_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
{ {
@@ -660,6 +688,13 @@ export const OASIS_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
NULL_ADDRESS, NULL_ADDRESS,
); );
export const KYBER_DMM_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
{
[ChainId.Mainnet]: '0x12807818B584a3Fa65D38B6C25B13983fE888D6E',
},
NULL_ADDRESS,
);
export const MOONISWAP_REGISTRIES_BY_CHAIN_ID = valueByChainId( export const MOONISWAP_REGISTRIES_BY_CHAIN_ID = valueByChainId(
{ {
[ChainId.Mainnet]: [ [ChainId.Mainnet]: [
@@ -933,6 +968,15 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
} }
return gas; return gas;
}, },
[ERC20BridgeSource.KyberDmm]: (fillData?: FillData) => {
// TODO: Different base cost if to/from ETH.
let gas = 95e3;
const path = (fillData as UniswapV2FillData).tokenAddressPath;
if (path.length > 2) {
gas += (path.length - 2) * 65e3; // +65k for each hop.
}
return gas;
},
// //
// BSC // BSC
// //

View File

@@ -5,8 +5,22 @@ export function getLiquidityProvidersForPair(
registry: LiquidityProviderRegistry, registry: LiquidityProviderRegistry,
takerToken: string, takerToken: string,
makerToken: string, makerToken: string,
): string[] { ): Array<{ providerAddress: string; gasCost: number }> {
return Object.entries(registry) return Object.entries(registry)
.filter(([, plp]) => [makerToken, takerToken].every(t => plp.tokens.includes(t))) .filter(([, plp]) => [makerToken, takerToken].every(t => plp.tokens.includes(t)))
.map(([providerAddress]) => providerAddress); .map(([providerAddress]) => {
let gasCost: number;
if (typeof registry[providerAddress].gasCost === 'number') {
gasCost = registry[providerAddress].gasCost as number;
} else {
gasCost = (registry[providerAddress].gasCost as (takerToken: string, makerToken: string) => number)(
takerToken,
makerToken,
);
}
return {
providerAddress,
gasCost,
};
});
} }

View File

@@ -89,6 +89,8 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
return encodeBridgeSourceId(BridgeProtocol.Dodo, 'Dodo'); return encodeBridgeSourceId(BridgeProtocol.Dodo, 'Dodo');
case ERC20BridgeSource.Kyber: case ERC20BridgeSource.Kyber:
return encodeBridgeSourceId(BridgeProtocol.Kyber, 'Kyber'); return encodeBridgeSourceId(BridgeProtocol.Kyber, 'Kyber');
case ERC20BridgeSource.KyberDmm:
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'KyberDmm');
case ERC20BridgeSource.LiquidityProvider: case ERC20BridgeSource.LiquidityProvider:
// "LiquidityProvider" is too long to encode (17 characters). // "LiquidityProvider" is too long to encode (17 characters).
return encodeBridgeSourceId(BridgeProtocol.Unknown, 'LP'); return encodeBridgeSourceId(BridgeProtocol.Unknown, 'LP');
@@ -176,6 +178,7 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
case ERC20BridgeSource.Linkswap: case ERC20BridgeSource.Linkswap:
case ERC20BridgeSource.PancakeSwap: case ERC20BridgeSource.PancakeSwap:
case ERC20BridgeSource.BakerySwap: case ERC20BridgeSource.BakerySwap:
case ERC20BridgeSource.KyberDmm:
const uniswapV2FillData = (order as OptimizedMarketBridgeOrder<UniswapV2FillData>).fillData; const uniswapV2FillData = (order as OptimizedMarketBridgeOrder<UniswapV2FillData>).fillData;
bridgeData = encoder.encode([uniswapV2FillData.router, uniswapV2FillData.tokenAddressPath]); bridgeData = encoder.encode([uniswapV2FillData.router, uniswapV2FillData.tokenAddressPath]);
break; break;
@@ -305,6 +308,7 @@ export const BRIDGE_ENCODERS: {
[ERC20BridgeSource.SushiSwap]: routerAddressPathEncoder, [ERC20BridgeSource.SushiSwap]: routerAddressPathEncoder,
[ERC20BridgeSource.CryptoCom]: routerAddressPathEncoder, [ERC20BridgeSource.CryptoCom]: routerAddressPathEncoder,
[ERC20BridgeSource.Linkswap]: routerAddressPathEncoder, [ERC20BridgeSource.Linkswap]: routerAddressPathEncoder,
[ERC20BridgeSource.KyberDmm]: routerAddressPathEncoder,
// Generic pools // Generic pools
[ERC20BridgeSource.Shell]: poolEncoder, [ERC20BridgeSource.Shell]: poolEncoder,
[ERC20BridgeSource.Mooniswap]: poolEncoder, [ERC20BridgeSource.Mooniswap]: poolEncoder,

View File

@@ -24,7 +24,7 @@ import {
DODOV2_FACTORIES_BY_CHAIN_ID, DODOV2_FACTORIES_BY_CHAIN_ID,
KYBER_CONFIG_BY_CHAIN_ID, KYBER_CONFIG_BY_CHAIN_ID,
LINKSWAP_ROUTER_BY_CHAIN_ID, LINKSWAP_ROUTER_BY_CHAIN_ID,
LIQUIDITY_PROVIDER_REGISTRY, LIQUIDITY_PROVIDER_REGISTRY_BY_CHAIN_ID,
MAKER_PSM_INFO_BY_CHAIN_ID, MAKER_PSM_INFO_BY_CHAIN_ID,
MAX_UINT256, MAX_UINT256,
MOONISWAP_REGISTRIES_BY_CHAIN_ID, MOONISWAP_REGISTRIES_BY_CHAIN_ID,
@@ -87,6 +87,7 @@ export const BATCH_SOURCE_FILTERS = SourceFilters.all().exclude([ERC20BridgeSour
* for use with `DexOrderSampler.executeAsync()`. * for use with `DexOrderSampler.executeAsync()`.
*/ */
export class SamplerOperations { export class SamplerOperations {
public readonly liquidityProviderRegistry: LiquidityProviderRegistry;
protected _bancorService?: BancorService; protected _bancorService?: BancorService;
public static constant<T>(result: T): BatchedOperation<T> { public static constant<T>(result: T): BatchedOperation<T> {
return { return {
@@ -102,9 +103,13 @@ export class SamplerOperations {
public readonly balancerPoolsCache: BalancerPoolsCache = new BalancerPoolsCache(), public readonly balancerPoolsCache: BalancerPoolsCache = new BalancerPoolsCache(),
public readonly creamPoolsCache: CreamPoolsCache = new CreamPoolsCache(), public readonly creamPoolsCache: CreamPoolsCache = new CreamPoolsCache(),
protected readonly tokenAdjacencyGraph: TokenAdjacencyGraph = { default: [] }, protected readonly tokenAdjacencyGraph: TokenAdjacencyGraph = { default: [] },
public readonly liquidityProviderRegistry: LiquidityProviderRegistry = LIQUIDITY_PROVIDER_REGISTRY, liquidityProviderRegistry: LiquidityProviderRegistry = {},
bancorServiceFn: () => Promise<BancorService | undefined> = async () => undefined, bancorServiceFn: () => Promise<BancorService | undefined> = async () => undefined,
) { ) {
this.liquidityProviderRegistry = {
...LIQUIDITY_PROVIDER_REGISTRY_BY_CHAIN_ID[chainId],
...liquidityProviderRegistry,
};
// Initialize the Bancor service, fetching paths in the background // Initialize the Bancor service, fetching paths in the background
bancorServiceFn() bancorServiceFn()
.then(service => (this._bancorService = service)) .then(service => (this._bancorService = service))
@@ -277,12 +282,13 @@ export class SamplerOperations {
makerToken: string, makerToken: string,
takerToken: string, takerToken: string,
takerFillAmounts: BigNumber[], takerFillAmounts: BigNumber[],
gasCost: number,
): SourceQuoteOperation<LiquidityProviderFillData> { ): SourceQuoteOperation<LiquidityProviderFillData> {
return new SamplerContractOperation({ return new SamplerContractOperation({
source: ERC20BridgeSource.LiquidityProvider, source: ERC20BridgeSource.LiquidityProvider,
fillData: { fillData: {
poolAddress: providerAddress, poolAddress: providerAddress,
gasCost: this.liquidityProviderRegistry[providerAddress].gasCost, gasCost,
}, },
contract: this._samplerContract, contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromLiquidityProvider, function: this._samplerContract.sampleSellsFromLiquidityProvider,
@@ -295,12 +301,13 @@ export class SamplerOperations {
makerToken: string, makerToken: string,
takerToken: string, takerToken: string,
makerFillAmounts: BigNumber[], makerFillAmounts: BigNumber[],
gasCost: number,
): SourceQuoteOperation<LiquidityProviderFillData> { ): SourceQuoteOperation<LiquidityProviderFillData> {
return new SamplerContractOperation({ return new SamplerContractOperation({
source: ERC20BridgeSource.LiquidityProvider, source: ERC20BridgeSource.LiquidityProvider,
fillData: { fillData: {
poolAddress: providerAddress, poolAddress: providerAddress,
gasCost: this.liquidityProviderRegistry[providerAddress].gasCost, gasCost,
}, },
contract: this._samplerContract, contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromLiquidityProvider, function: this._samplerContract.sampleBuysFromLiquidityProvider,
@@ -1022,6 +1029,7 @@ export class SamplerOperations {
case ERC20BridgeSource.CryptoCom: case ERC20BridgeSource.CryptoCom:
case ERC20BridgeSource.PancakeSwap: case ERC20BridgeSource.PancakeSwap:
case ERC20BridgeSource.BakerySwap: case ERC20BridgeSource.BakerySwap:
case ERC20BridgeSource.KyberDmm:
const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source); const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source);
if (!isValidAddress(uniLikeRouter)) { if (!isValidAddress(uniLikeRouter)) {
return []; return [];
@@ -1060,8 +1068,14 @@ export class SamplerOperations {
this.liquidityProviderRegistry, this.liquidityProviderRegistry,
takerToken, takerToken,
makerToken, makerToken,
).map(pool => ).map(({ providerAddress, gasCost }) =>
this.getLiquidityProviderSellQuotes(pool, makerToken, takerToken, takerFillAmounts), this.getLiquidityProviderSellQuotes(
providerAddress,
makerToken,
takerToken,
takerFillAmounts,
gasCost,
),
); );
case ERC20BridgeSource.MStable: case ERC20BridgeSource.MStable:
return isValidAddress(MSTABLE_ROUTER_BY_CHAIN_ID[this.chainId]) return isValidAddress(MSTABLE_ROUTER_BY_CHAIN_ID[this.chainId])
@@ -1213,6 +1227,7 @@ export class SamplerOperations {
case ERC20BridgeSource.CryptoCom: case ERC20BridgeSource.CryptoCom:
case ERC20BridgeSource.PancakeSwap: case ERC20BridgeSource.PancakeSwap:
case ERC20BridgeSource.BakerySwap: case ERC20BridgeSource.BakerySwap:
case ERC20BridgeSource.KyberDmm:
const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source); const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source);
if (!isValidAddress(uniLikeRouter)) { if (!isValidAddress(uniLikeRouter)) {
return []; return [];
@@ -1251,8 +1266,14 @@ export class SamplerOperations {
this.liquidityProviderRegistry, this.liquidityProviderRegistry,
takerToken, takerToken,
makerToken, makerToken,
).map(pool => ).map(({ providerAddress, gasCost }) =>
this.getLiquidityProviderBuyQuotes(pool, makerToken, takerToken, makerFillAmounts), this.getLiquidityProviderBuyQuotes(
providerAddress,
makerToken,
takerToken,
makerFillAmounts,
gasCost,
),
); );
case ERC20BridgeSource.MStable: case ERC20BridgeSource.MStable:
return isValidAddress(MSTABLE_ROUTER_BY_CHAIN_ID[this.chainId]) return isValidAddress(MSTABLE_ROUTER_BY_CHAIN_ID[this.chainId])

View File

@@ -59,6 +59,7 @@ export enum ERC20BridgeSource {
DodoV2 = 'DODO_V2', DodoV2 = 'DODO_V2',
CryptoCom = 'CryptoCom', CryptoCom = 'CryptoCom',
Linkswap = 'Linkswap', Linkswap = 'Linkswap',
KyberDmm = 'KyberDMM',
// Other // Other
PancakeSwap = 'PancakeSwap', PancakeSwap = 'PancakeSwap',
BakerySwap = 'BakerySwap', BakerySwap = 'BakerySwap',
@@ -439,7 +440,7 @@ export interface TokenAdjacencyGraph {
export interface LiquidityProviderRegistry { export interface LiquidityProviderRegistry {
[address: string]: { [address: string]: {
tokens: string[]; tokens: string[];
gasCost: number; gasCost: number | ((takerToken: string, makerToken: string) => number);
}; };
} }

View File

@@ -68,6 +68,7 @@ const DEFAULT_EXCLUDED = [
ERC20BridgeSource.PancakeSwap, ERC20BridgeSource.PancakeSwap,
ERC20BridgeSource.BakerySwap, ERC20BridgeSource.BakerySwap,
ERC20BridgeSource.MakerPsm, ERC20BridgeSource.MakerPsm,
ERC20BridgeSource.KyberDmm,
]; ];
const BUY_SOURCES = BUY_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Mainnet].sources; const BUY_SOURCES = BUY_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Mainnet].sources;
const SELL_SOURCES = SELL_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Mainnet].sources; const SELL_SOURCES = SELL_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Mainnet].sources;
@@ -282,32 +283,12 @@ describe('MarketOperationUtils tests', () => {
[source: string]: Numberish[]; [source: string]: Numberish[];
} }
const ZERO_RATES: RatesBySource = { const ZERO_RATES: RatesBySource = Object.assign(
[ERC20BridgeSource.Native]: _.times(NUM_SAMPLES, () => 0), {},
[ERC20BridgeSource.Eth2Dai]: _.times(NUM_SAMPLES, () => 0), ...Object.values(ERC20BridgeSource).map(source => ({
[ERC20BridgeSource.Uniswap]: _.times(NUM_SAMPLES, () => 0), [source]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.Kyber]: _.times(NUM_SAMPLES, () => 0), })),
[ERC20BridgeSource.UniswapV2]: _.times(NUM_SAMPLES, () => 0), );
[ERC20BridgeSource.Balancer]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.Bancor]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.Curve]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.LiquidityProvider]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.MStable]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.Mooniswap]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.Swerve]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.SnowSwap]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.SushiSwap]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.MultiHop]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.Shell]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.Cream]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.Dodo]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.DodoV2]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.CryptoCom]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.Linkswap]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.PancakeSwap]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.BakerySwap]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.MakerPsm]: _.times(NUM_SAMPLES, () => 0),
};
const DEFAULT_RATES: RatesBySource = { const DEFAULT_RATES: RatesBySource = {
...ZERO_RATES, ...ZERO_RATES,
@@ -372,6 +353,7 @@ describe('MarketOperationUtils tests', () => {
[ERC20BridgeSource.Uniswap]: { router: randomAddress() }, [ERC20BridgeSource.Uniswap]: { router: randomAddress() },
[ERC20BridgeSource.Eth2Dai]: { router: randomAddress() }, [ERC20BridgeSource.Eth2Dai]: { router: randomAddress() },
[ERC20BridgeSource.MakerPsm]: {}, [ERC20BridgeSource.MakerPsm]: {},
[ERC20BridgeSource.KyberDmm]: { tokenAddressPath: [] },
}; };
const DEFAULT_OPS = { const DEFAULT_OPS = {