Merge pull request #2729 from 0xProject/feat/snowswap

feat: SnowSwap
This commit is contained in:
Romain Butteaud 2020-10-19 16:21:31 -07:00 committed by GitHub
commit 9cb21006a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 198 additions and 29 deletions

View File

@ -37,7 +37,7 @@ contract CurveSampler is
/// @dev Base gas limit for Curve calls. Some Curves have multiple tokens /// @dev Base gas limit for Curve calls. Some Curves have multiple tokens
/// So a reasonable ceil is 150k per token. Biggest Curve has 4 tokens. /// So a reasonable ceil is 150k per token. Biggest Curve has 4 tokens.
uint256 constant private CURVE_CALL_GAS = 600e3; // 600k uint256 constant private CURVE_CALL_GAS = 2000e3; // Was 600k for Curve but SnowSwap is using 1500k+
/// @dev Sample sell quotes from Curve. /// @dev Sample sell quotes from Curve.
/// @param curveInfo Curve information specific to this token pair. /// @param curveInfo Curve information specific to this token pair.

View File

@ -155,6 +155,8 @@ export {
SushiSwapFillData, SushiSwapFillData,
SwerveFillData, SwerveFillData,
SwerveInfo, SwerveInfo,
SnowSwapFillData,
SnowSwapInfo,
TokenAdjacencyGraph, TokenAdjacencyGraph,
UniswapV2FillData, UniswapV2FillData,
} from './utils/market_operation_utils/types'; } from './utils/market_operation_utils/types';

View File

@ -21,6 +21,7 @@ export const SELL_SOURCE_FILTER = new SourceFilters([
ERC20BridgeSource.MStable, ERC20BridgeSource.MStable,
ERC20BridgeSource.Mooniswap, ERC20BridgeSource.Mooniswap,
ERC20BridgeSource.Swerve, ERC20BridgeSource.Swerve,
ERC20BridgeSource.SnowSwap,
ERC20BridgeSource.SushiSwap, ERC20BridgeSource.SushiSwap,
ERC20BridgeSource.Shell, ERC20BridgeSource.Shell,
ERC20BridgeSource.MultiHop, ERC20BridgeSource.MultiHop,
@ -45,6 +46,7 @@ export const BUY_SOURCE_FILTER = new SourceFilters(
ERC20BridgeSource.Mooniswap, ERC20BridgeSource.Mooniswap,
ERC20BridgeSource.Shell, ERC20BridgeSource.Shell,
ERC20BridgeSource.Swerve, ERC20BridgeSource.Swerve,
ERC20BridgeSource.SnowSwap,
ERC20BridgeSource.SushiSwap, ERC20BridgeSource.SushiSwap,
ERC20BridgeSource.MultiHop, ERC20BridgeSource.MultiHop,
ERC20BridgeSource.Dodo, ERC20BridgeSource.Dodo,
@ -172,9 +174,9 @@ export const MAINNET_CURVE_INFOS: { [name: string]: CurveInfo } = {
export const MAINNET_SWERVE_INFOS: { [name: string]: CurveInfo } = { export const MAINNET_SWERVE_INFOS: { [name: string]: CurveInfo } = {
swUSD: { swUSD: {
exchangeFunctionSelector: CurveFunctionSelectors.exchange, exchangeFunctionSelector: CurveFunctionSelectors.exchange,
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy,
buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx_underlying, buyQuoteFunctionSelector: CurveFunctionSelectors.None,
poolAddress: '0x329239599afB305DA0A2eC69c58F8a6697F9F88d', poolAddress: '0x329239599afb305da0a2ec69c58f8a6697f9f88d', // _target: 0xa5407eae9ba41422680e2e00537571bcc53efbfd
tokens: [ tokens: [
'0x6b175474e89094c44da98b954eedeac495271d0f', '0x6b175474e89094c44da98b954eedeac495271d0f',
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
@ -183,6 +185,53 @@ export const MAINNET_SWERVE_INFOS: { [name: string]: CurveInfo } = {
], ],
}, },
}; };
export const MAINNET_SNOWSWAP_INFOS: { [name: string]: CurveInfo } = {
yVaultCurve: {
exchangeFunctionSelector: CurveFunctionSelectors.exchange,
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy,
buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx,
poolAddress: '0xbf7ccd6c446acfcc5df023043f2167b62e81899b',
tokens: [
'0x5dbcf33d8c2e976c6b560249878e6f1491bca25c', // yUSD
'0x2994529c0652d127b7842094103715ec5299bbed', // ybCRV
],
},
yVaultCurveUnderlying: {
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx_underlying,
poolAddress: '0xbf7ccd6c446acfcc5df023043f2167b62e81899b',
tokens: [
'0xdf5e0e81dff6faf3a7e52ba697820c5e32d806a8', // yCRV
'0x3b3ac5386837dc563660fb6a0937dfaa5924333b', // bCRV
],
},
yVaultUSD: {
exchangeFunctionSelector: CurveFunctionSelectors.exchange,
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy,
buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx,
poolAddress: '0x4571753311e37ddb44faa8fb78a6df9a6e3c6c0b',
tokens: [
'0xacd43e627e64355f1861cec6d3a6688b31a6f952', // yDAI
'0x597ad1e0c13bfe8025993d9e79c69e1c0233522e', // yUSDC
'0x2f08119c6f07c006695e079aafc638b8789faf18', // yUSDT
'0x37d19d1c4e1fa9dc47bd1ea12f742a0887eda74a', // yTUSD
],
},
// Gas is too high for these underlying tokens (3M+)
// yVaultUSDUnderlying: {
// exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
// sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
// buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx_underlying,
// poolAddress: '0x4571753311e37ddb44faa8fb78a6df9a6e3c6c0b',
// tokens: [
// '0x6b175474e89094c44da98b954eedeac495271d0f', // DAI
// '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // USDC
// '0xdac17f958d2ee523a2206206994597c13d831ec7', // USDT
// '0x0000000000085d4780b73119b644ae5ecd22b376', // TUSD
// ],
// },
};
export const MAINNET_KYBER_RESERVE_IDS: { [name: string]: string } = { export const MAINNET_KYBER_RESERVE_IDS: { [name: string]: string } = {
Reserve1: '0xff4b796265722046707200000000000000000000000000000000000000000000', Reserve1: '0xff4b796265722046707200000000000000000000000000000000000000000000',

View File

@ -1,5 +1,5 @@
import { MAINNET_CURVE_INFOS, MAINNET_SWERVE_INFOS } from './constants'; import { MAINNET_CURVE_INFOS, MAINNET_SNOWSWAP_INFOS, MAINNET_SWERVE_INFOS } from './constants';
import { CurveInfo, SwerveInfo } from './types'; import { CurveInfo, SnowSwapInfo, SwerveInfo } from './types';
// tslint:disable completed-docs // tslint:disable completed-docs
export function getCurveInfosForPair(takerToken: string, makerToken: string): CurveInfo[] { export function getCurveInfosForPair(takerToken: string, makerToken: string): CurveInfo[] {
@ -9,3 +9,7 @@ export function getCurveInfosForPair(takerToken: string, makerToken: string): Cu
export function getSwerveInfosForPair(takerToken: string, makerToken: string): SwerveInfo[] { export function getSwerveInfosForPair(takerToken: string, makerToken: string): SwerveInfo[] {
return Object.values(MAINNET_SWERVE_INFOS).filter(c => [makerToken, takerToken].every(t => c.tokens.includes(t))); return Object.values(MAINNET_SWERVE_INFOS).filter(c => [makerToken, takerToken].every(t => c.tokens.includes(t)));
} }
export function getSnowSwapInfosForPair(takerToken: string, makerToken: string): SnowSwapInfo[] {
return Object.values(MAINNET_SNOWSWAP_INFOS).filter(c => [makerToken, takerToken].every(t => c.tokens.includes(t)));
}

View File

@ -34,6 +34,7 @@ import {
NativeCollapsedFill, NativeCollapsedFill,
OptimizedMarketOrder, OptimizedMarketOrder,
OrderDomain, OrderDomain,
SnowSwapFillData,
SushiSwapFillData, SushiSwapFillData,
SwerveFillData, SwerveFillData,
UniswapV2FillData, UniswapV2FillData,
@ -173,6 +174,8 @@ function getBridgeAddressFromFill(fill: CollapsedFill, opts: CreateOrderFromPath
return opts.contractAddresses.curveBridge; return opts.contractAddresses.curveBridge;
case ERC20BridgeSource.Swerve: case ERC20BridgeSource.Swerve:
return opts.contractAddresses.curveBridge; return opts.contractAddresses.curveBridge;
case ERC20BridgeSource.SnowSwap:
return opts.contractAddresses.curveBridge;
case ERC20BridgeSource.Bancor: case ERC20BridgeSource.Bancor:
return opts.contractAddresses.bancorBridge; return opts.contractAddresses.bancorBridge;
case ERC20BridgeSource.Balancer: case ERC20BridgeSource.Balancer:
@ -213,8 +216,8 @@ export function createBridgeOrder(
makerToken, makerToken,
bridgeAddress, bridgeAddress,
createCurveBridgeData( createCurveBridgeData(
curveFillData.curve.poolAddress, curveFillData.pool.poolAddress,
curveFillData.curve.exchangeFunctionSelector, curveFillData.pool.exchangeFunctionSelector,
takerToken, takerToken,
curveFillData.fromTokenIdx, curveFillData.fromTokenIdx,
curveFillData.toTokenIdx, curveFillData.toTokenIdx,
@ -235,6 +238,20 @@ export function createBridgeOrder(
), ),
); );
break; break;
case ERC20BridgeSource.SnowSwap:
const snowSwapFillData = (fill as CollapsedFill<SnowSwapFillData>).fillData!; // tslint:disable-line:no-non-null-assertion
makerAssetData = assetDataUtils.encodeERC20BridgeAssetData(
makerToken,
bridgeAddress,
createCurveBridgeData(
snowSwapFillData.pool.poolAddress,
snowSwapFillData.pool.exchangeFunctionSelector,
takerToken,
snowSwapFillData.fromTokenIdx,
snowSwapFillData.toTokenIdx,
),
);
break;
case ERC20BridgeSource.Balancer: case ERC20BridgeSource.Balancer:
const balancerFillData = (fill as CollapsedFill<BalancerFillData>).fillData!; // tslint:disable-line:no-non-null-assertion const balancerFillData = (fill as CollapsedFill<BalancerFillData>).fillData!; // tslint:disable-line:no-non-null-assertion
makerAssetData = assetDataUtils.encodeERC20BridgeAssetData( makerAssetData = assetDataUtils.encodeERC20BridgeAssetData(

View File

@ -9,7 +9,7 @@ import { BalancerPoolsCache, computeBalancerBuyQuote, computeBalancerSellQuote }
import { BancorService } from './bancor_service'; import { BancorService } from './bancor_service';
import { MAINNET_SUSHI_SWAP_ROUTER, MAX_UINT256, NULL_BYTES, ZERO_AMOUNT } from './constants'; import { MAINNET_SUSHI_SWAP_ROUTER, MAX_UINT256, NULL_BYTES, ZERO_AMOUNT } from './constants';
import { CreamPoolsCache } from './cream_utils'; import { CreamPoolsCache } from './cream_utils';
import { getCurveInfosForPair, getSwerveInfosForPair } from './curve_utils'; import { getCurveInfosForPair, getSnowSwapInfosForPair, getSwerveInfosForPair } from './curve_utils';
import { getKyberReserveIdsForPair } from './kyber_utils'; import { getKyberReserveIdsForPair } from './kyber_utils';
import { getMultiBridgeIntermediateToken } from './multibridge_utils'; import { getMultiBridgeIntermediateToken } from './multibridge_utils';
import { getIntermediateTokens } from './multihop_utils'; import { getIntermediateTokens } from './multihop_utils';
@ -30,6 +30,8 @@ import {
MooniswapFillData, MooniswapFillData,
MultiBridgeFillData, MultiBridgeFillData,
MultiHopFillData, MultiHopFillData,
SnowSwapFillData,
SnowSwapInfo,
SourceQuoteOperation, SourceQuoteOperation,
SushiSwapFillData, SushiSwapFillData,
SwerveFillData, SwerveFillData,
@ -296,7 +298,7 @@ export class SamplerOperations {
} }
public getCurveSellQuotes( public getCurveSellQuotes(
curve: CurveInfo, pool: CurveInfo,
fromTokenIdx: number, fromTokenIdx: number,
toTokenIdx: number, toTokenIdx: number,
takerFillAmounts: BigNumber[], takerFillAmounts: BigNumber[],
@ -304,7 +306,7 @@ export class SamplerOperations {
return new SamplerContractOperation({ return new SamplerContractOperation({
source: ERC20BridgeSource.Curve, source: ERC20BridgeSource.Curve,
fillData: { fillData: {
curve, pool,
fromTokenIdx, fromTokenIdx,
toTokenIdx, toTokenIdx,
}, },
@ -312,9 +314,9 @@ export class SamplerOperations {
function: this._samplerContract.sampleSellsFromCurve, function: this._samplerContract.sampleSellsFromCurve,
params: [ params: [
{ {
poolAddress: curve.poolAddress, poolAddress: pool.poolAddress,
sellQuoteFunctionSelector: curve.sellQuoteFunctionSelector, sellQuoteFunctionSelector: pool.sellQuoteFunctionSelector,
buyQuoteFunctionSelector: curve.buyQuoteFunctionSelector, buyQuoteFunctionSelector: pool.buyQuoteFunctionSelector,
}, },
new BigNumber(fromTokenIdx), new BigNumber(fromTokenIdx),
new BigNumber(toTokenIdx), new BigNumber(toTokenIdx),
@ -324,7 +326,7 @@ export class SamplerOperations {
} }
public getCurveBuyQuotes( public getCurveBuyQuotes(
curve: CurveInfo, pool: CurveInfo,
fromTokenIdx: number, fromTokenIdx: number,
toTokenIdx: number, toTokenIdx: number,
makerFillAmounts: BigNumber[], makerFillAmounts: BigNumber[],
@ -332,7 +334,7 @@ export class SamplerOperations {
return new SamplerContractOperation({ return new SamplerContractOperation({
source: ERC20BridgeSource.Curve, source: ERC20BridgeSource.Curve,
fillData: { fillData: {
curve, pool,
fromTokenIdx, fromTokenIdx,
toTokenIdx, toTokenIdx,
}, },
@ -340,9 +342,9 @@ export class SamplerOperations {
function: this._samplerContract.sampleBuysFromCurve, function: this._samplerContract.sampleBuysFromCurve,
params: [ params: [
{ {
poolAddress: curve.poolAddress, poolAddress: pool.poolAddress,
sellQuoteFunctionSelector: curve.sellQuoteFunctionSelector, sellQuoteFunctionSelector: pool.sellQuoteFunctionSelector,
buyQuoteFunctionSelector: curve.buyQuoteFunctionSelector, buyQuoteFunctionSelector: pool.buyQuoteFunctionSelector,
}, },
new BigNumber(fromTokenIdx), new BigNumber(fromTokenIdx),
new BigNumber(toTokenIdx), new BigNumber(toTokenIdx),
@ -407,6 +409,62 @@ export class SamplerOperations {
}); });
} }
public getSnowSwapSellQuotes(
pool: SnowSwapInfo,
fromTokenIdx: number,
toTokenIdx: number,
takerFillAmounts: BigNumber[],
): SourceQuoteOperation<SnowSwapFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.SnowSwap,
fillData: {
pool,
fromTokenIdx,
toTokenIdx,
},
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromCurve,
params: [
{
poolAddress: pool.poolAddress,
sellQuoteFunctionSelector: pool.sellQuoteFunctionSelector,
buyQuoteFunctionSelector: pool.buyQuoteFunctionSelector,
},
new BigNumber(fromTokenIdx),
new BigNumber(toTokenIdx),
takerFillAmounts,
],
});
}
public getSnowSwapBuyQuotes(
pool: SnowSwapInfo,
fromTokenIdx: number,
toTokenIdx: number,
makerFillAmounts: BigNumber[],
): SourceQuoteOperation<SnowSwapFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.SnowSwap,
fillData: {
pool,
fromTokenIdx,
toTokenIdx,
},
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromCurve,
params: [
{
poolAddress: pool.poolAddress,
sellQuoteFunctionSelector: pool.sellQuoteFunctionSelector,
buyQuoteFunctionSelector: pool.buyQuoteFunctionSelector,
},
new BigNumber(fromTokenIdx),
new BigNumber(toTokenIdx),
makerFillAmounts,
],
});
}
public getBalancerSellQuotes( public getBalancerSellQuotes(
poolAddress: string, poolAddress: string,
makerToken: string, makerToken: string,
@ -1024,11 +1082,11 @@ export class SamplerOperations {
this.getKyberSellQuotes(reserveId, makerToken, takerToken, takerFillAmounts), this.getKyberSellQuotes(reserveId, makerToken, takerToken, takerFillAmounts),
); );
case ERC20BridgeSource.Curve: case ERC20BridgeSource.Curve:
return getCurveInfosForPair(takerToken, makerToken).map(curve => return getCurveInfosForPair(takerToken, makerToken).map(pool =>
this.getCurveSellQuotes( this.getCurveSellQuotes(
curve, pool,
curve.tokens.indexOf(takerToken), pool.tokens.indexOf(takerToken),
curve.tokens.indexOf(makerToken), pool.tokens.indexOf(makerToken),
takerFillAmounts, takerFillAmounts,
), ),
); );
@ -1041,6 +1099,15 @@ export class SamplerOperations {
takerFillAmounts, takerFillAmounts,
), ),
); );
case ERC20BridgeSource.SnowSwap:
return getSnowSwapInfosForPair(takerToken, makerToken).map(pool =>
this.getSnowSwapSellQuotes(
pool,
pool.tokens.indexOf(takerToken),
pool.tokens.indexOf(makerToken),
takerFillAmounts,
),
);
case ERC20BridgeSource.LiquidityProvider: case ERC20BridgeSource.LiquidityProvider:
if (liquidityProviderRegistryAddress === undefined) { if (liquidityProviderRegistryAddress === undefined) {
throw new Error( throw new Error(
@ -1147,11 +1214,11 @@ export class SamplerOperations {
this.getKyberBuyQuotes(reserveId, makerToken, takerToken, makerFillAmounts), this.getKyberBuyQuotes(reserveId, makerToken, takerToken, makerFillAmounts),
); );
case ERC20BridgeSource.Curve: case ERC20BridgeSource.Curve:
return getCurveInfosForPair(takerToken, makerToken).map(curve => return getCurveInfosForPair(takerToken, makerToken).map(pool =>
this.getCurveBuyQuotes( this.getCurveBuyQuotes(
curve, pool,
curve.tokens.indexOf(takerToken), pool.tokens.indexOf(takerToken),
curve.tokens.indexOf(makerToken), pool.tokens.indexOf(makerToken),
makerFillAmounts, makerFillAmounts,
), ),
); );
@ -1164,6 +1231,15 @@ export class SamplerOperations {
makerFillAmounts, makerFillAmounts,
), ),
); );
case ERC20BridgeSource.SnowSwap:
return getSnowSwapInfosForPair(takerToken, makerToken).map(pool =>
this.getSnowSwapBuyQuotes(
pool,
pool.tokens.indexOf(takerToken),
pool.tokens.indexOf(makerToken),
makerFillAmounts,
),
);
case ERC20BridgeSource.LiquidityProvider: case ERC20BridgeSource.LiquidityProvider:
if (liquidityProviderRegistryAddress === undefined) { if (liquidityProviderRegistryAddress === undefined) {
throw new Error( throw new Error(

View File

@ -44,6 +44,7 @@ export enum ERC20BridgeSource {
MultiHop = 'MultiHop', MultiHop = 'MultiHop',
Shell = 'Shell', Shell = 'Shell',
Swerve = 'Swerve', Swerve = 'Swerve',
SnowSwap = 'SnowSwap',
SushiSwap = 'SushiSwap', SushiSwap = 'SushiSwap',
Dodo = 'DODO', Dodo = 'DODO',
} }
@ -75,6 +76,7 @@ export interface CurveInfo {
} }
export interface SwerveInfo extends CurveInfo {} export interface SwerveInfo extends CurveInfo {}
export interface SnowSwapInfo extends CurveInfo {}
// Internal `fillData` field for `Fill` objects. // Internal `fillData` field for `Fill` objects.
export interface FillData {} export interface FillData {}
@ -92,7 +94,7 @@ export interface NativeFillData extends FillData {
export interface CurveFillData extends FillData { export interface CurveFillData extends FillData {
fromTokenIdx: number; fromTokenIdx: number;
toTokenIdx: number; toTokenIdx: number;
curve: CurveInfo; pool: CurveInfo;
} }
export interface SwerveFillData extends FillData { export interface SwerveFillData extends FillData {
@ -101,6 +103,12 @@ export interface SwerveFillData extends FillData {
pool: SwerveInfo; pool: SwerveInfo;
} }
export interface SnowSwapFillData extends FillData {
fromTokenIdx: number;
toTokenIdx: number;
pool: SnowSwapInfo;
}
export interface BalancerFillData extends FillData { export interface BalancerFillData extends FillData {
poolAddress: string; poolAddress: string;
} }

View File

@ -43,6 +43,7 @@ const DEFAULT_EXCLUDED = [
ERC20BridgeSource.Mooniswap, ERC20BridgeSource.Mooniswap,
ERC20BridgeSource.Bancor, ERC20BridgeSource.Bancor,
ERC20BridgeSource.Swerve, ERC20BridgeSource.Swerve,
ERC20BridgeSource.SnowSwap,
ERC20BridgeSource.SushiSwap, ERC20BridgeSource.SushiSwap,
ERC20BridgeSource.MultiHop, ERC20BridgeSource.MultiHop,
ERC20BridgeSource.Shell, ERC20BridgeSource.Shell,
@ -284,6 +285,7 @@ describe('MarketOperationUtils tests', () => {
[ERC20BridgeSource.MStable]: _.times(NUM_SAMPLES, () => 0), [ERC20BridgeSource.MStable]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.Mooniswap]: _.times(NUM_SAMPLES, () => 0), [ERC20BridgeSource.Mooniswap]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.Swerve]: _.times(NUM_SAMPLES, () => 0), [ERC20BridgeSource.Swerve]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.SnowSwap]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.SushiSwap]: _.times(NUM_SAMPLES, () => 0), [ERC20BridgeSource.SushiSwap]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.MultiHop]: _.times(NUM_SAMPLES, () => 0), [ERC20BridgeSource.MultiHop]: _.times(NUM_SAMPLES, () => 0),
[ERC20BridgeSource.Shell]: _.times(NUM_SAMPLES, () => 0), [ERC20BridgeSource.Shell]: _.times(NUM_SAMPLES, () => 0),
@ -308,7 +310,7 @@ describe('MarketOperationUtils tests', () => {
[ERC20BridgeSource.Bancor]: { path: [], networkAddress: randomAddress() }, [ERC20BridgeSource.Bancor]: { path: [], networkAddress: randomAddress() },
[ERC20BridgeSource.Kyber]: { hint: '0x', reserveId: '0x' }, [ERC20BridgeSource.Kyber]: { hint: '0x', reserveId: '0x' },
[ERC20BridgeSource.Curve]: { [ERC20BridgeSource.Curve]: {
curve: { pool: {
poolAddress: randomAddress(), poolAddress: randomAddress(),
tokens: [TAKER_TOKEN, MAKER_TOKEN], tokens: [TAKER_TOKEN, MAKER_TOKEN],
exchangeFunctionSelector: hexUtils.random(4), exchangeFunctionSelector: hexUtils.random(4),
@ -329,6 +331,17 @@ describe('MarketOperationUtils tests', () => {
fromTokenIdx: 0, fromTokenIdx: 0,
toTokenIdx: 1, toTokenIdx: 1,
}, },
[ERC20BridgeSource.SnowSwap]: {
pool: {
poolAddress: randomAddress(),
tokens: [TAKER_TOKEN, MAKER_TOKEN],
exchangeFunctionSelector: hexUtils.random(4),
sellQuoteFunctionSelector: hexUtils.random(4),
buyQuoteFunctionSelector: hexUtils.random(4),
},
fromTokenIdx: 0,
toTokenIdx: 1,
},
[ERC20BridgeSource.LiquidityProvider]: { poolAddress: randomAddress() }, [ERC20BridgeSource.LiquidityProvider]: { poolAddress: randomAddress() },
[ERC20BridgeSource.SushiSwap]: { tokenAddressPath: [] }, [ERC20BridgeSource.SushiSwap]: { tokenAddressPath: [] },
[ERC20BridgeSource.Mooniswap]: { poolAddress: randomAddress() }, [ERC20BridgeSource.Mooniswap]: { poolAddress: randomAddress() },