From 891aa8e8bfbb8875631b236e51450e62e040c17c Mon Sep 17 00:00:00 2001 From: Romain Butteaud Date: Tue, 13 Oct 2020 17:06:37 -0700 Subject: [PATCH 1/7] feat: SnowSwap --- packages/asset-swapper/src/index.ts | 2 + .../utils/market_operation_utils/constants.ts | 28 ++++++- .../market_operation_utils/curve_utils.ts | 8 +- .../utils/market_operation_utils/orders.ts | 17 ++++ .../sampler_operations.ts | 78 ++++++++++++++++++- .../src/utils/market_operation_utils/types.ts | 8 ++ .../test/market_operation_utils_test.ts | 13 ++++ 7 files changed, 150 insertions(+), 4 deletions(-) diff --git a/packages/asset-swapper/src/index.ts b/packages/asset-swapper/src/index.ts index 0c87279cc8..21fcc1b3b9 100644 --- a/packages/asset-swapper/src/index.ts +++ b/packages/asset-swapper/src/index.ts @@ -155,6 +155,8 @@ export { SushiSwapFillData, SwerveFillData, SwerveInfo, + SnowSwapFillData, + SnowSwapInfo, TokenAdjacencyGraph, UniswapV2FillData, } from './utils/market_operation_utils/types'; diff --git a/packages/asset-swapper/src/utils/market_operation_utils/constants.ts b/packages/asset-swapper/src/utils/market_operation_utils/constants.ts index 1bb895690c..28d5bfa1e8 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/constants.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/constants.ts @@ -21,6 +21,7 @@ export const SELL_SOURCE_FILTER = new SourceFilters([ ERC20BridgeSource.MStable, ERC20BridgeSource.Mooniswap, ERC20BridgeSource.Swerve, + ERC20BridgeSource.SnowSwap, ERC20BridgeSource.SushiSwap, ERC20BridgeSource.Shell, ERC20BridgeSource.MultiHop, @@ -45,6 +46,7 @@ export const BUY_SOURCE_FILTER = new SourceFilters( ERC20BridgeSource.Mooniswap, ERC20BridgeSource.Shell, ERC20BridgeSource.Swerve, + ERC20BridgeSource.SnowSwap, ERC20BridgeSource.SushiSwap, ERC20BridgeSource.MultiHop, ERC20BridgeSource.Dodo, @@ -173,7 +175,7 @@ export const MAINNET_SWERVE_INFOS: { [name: string]: CurveInfo } = { swUSD: { exchangeFunctionSelector: CurveFunctionSelectors.exchange, sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, - buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx_underlying, + buyQuoteFunctionSelector: CurveFunctionSelectors.None, poolAddress: '0x329239599afB305DA0A2eC69c58F8a6697F9F88d', tokens: [ '0x6b175474e89094c44da98b954eedeac495271d0f', @@ -183,6 +185,30 @@ export const MAINNET_SWERVE_INFOS: { [name: string]: CurveInfo } = { ], }, }; +export const MAINNET_SNOWSWAP_INFOS: { [name: string]: CurveInfo } = { + yVaultCurve: { + exchangeFunctionSelector: CurveFunctionSelectors.exchange, + sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, + buyQuoteFunctionSelector: CurveFunctionSelectors.None, + poolAddress: '0xBf7CCD6C446acfcc5dF023043f2167B62E81899b', + tokens: [ + '0x5dbcf33d8c2e976c6b560249878e6f1491bca25c', // yUSD + '0x2994529c0652d127b7842094103715ec5299bbed', // ybCRV + ], + }, + yVaultUSD: { + exchangeFunctionSelector: CurveFunctionSelectors.exchange, + sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, + buyQuoteFunctionSelector: CurveFunctionSelectors.None, + poolAddress: '0x4571753311E37dDb44faA8Fb78a6dF9a6E3c6C0B', + tokens: [ + '0x597ad1e0c13bfe8025993d9e79c69e1c0233522e', // yUSDC + '0xacd43e627e64355f1861cec6d3a6688b31a6f952', // yDAI + '0x2f08119c6f07c006695e079aafc638b8789faf18', // yUSDT + '0x37d19d1c4e1fa9dc47bd1ea12f742a0887eda74a', // yTUSD + ], + }, +}; export const MAINNET_KYBER_RESERVE_IDS: { [name: string]: string } = { Reserve1: '0xff4b796265722046707200000000000000000000000000000000000000000000', diff --git a/packages/asset-swapper/src/utils/market_operation_utils/curve_utils.ts b/packages/asset-swapper/src/utils/market_operation_utils/curve_utils.ts index e1b70ab492..84bc42df9b 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/curve_utils.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/curve_utils.ts @@ -1,5 +1,5 @@ -import { MAINNET_CURVE_INFOS, MAINNET_SWERVE_INFOS } from './constants'; -import { CurveInfo, SwerveInfo } from './types'; +import { MAINNET_CURVE_INFOS, MAINNET_SNOWSWAP_INFOS, MAINNET_SWERVE_INFOS } from './constants'; +import { CurveInfo, SnowSwapInfo, SwerveInfo } from './types'; // tslint:disable completed-docs 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[] { 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))); +} \ No newline at end of file diff --git a/packages/asset-swapper/src/utils/market_operation_utils/orders.ts b/packages/asset-swapper/src/utils/market_operation_utils/orders.ts index e06b815718..efadab35ff 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/orders.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/orders.ts @@ -34,6 +34,7 @@ import { NativeCollapsedFill, OptimizedMarketOrder, OrderDomain, + SnowSwapFillData, SushiSwapFillData, SwerveFillData, UniswapV2FillData, @@ -173,6 +174,8 @@ function getBridgeAddressFromFill(fill: CollapsedFill, opts: CreateOrderFromPath return opts.contractAddresses.curveBridge; case ERC20BridgeSource.Swerve: return opts.contractAddresses.curveBridge; + case ERC20BridgeSource.SnowSwap: + return opts.contractAddresses.curveBridge; case ERC20BridgeSource.Bancor: return opts.contractAddresses.bancorBridge; case ERC20BridgeSource.Balancer: @@ -235,6 +238,20 @@ export function createBridgeOrder( ), ); break; + case ERC20BridgeSource.SnowSwap: + const snowSwapFillData = (fill as CollapsedFill).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: const balancerFillData = (fill as CollapsedFill).fillData!; // tslint:disable-line:no-non-null-assertion makerAssetData = assetDataUtils.encodeERC20BridgeAssetData( diff --git a/packages/asset-swapper/src/utils/market_operation_utils/sampler_operations.ts b/packages/asset-swapper/src/utils/market_operation_utils/sampler_operations.ts index 5d5b0385a8..a38c97aa00 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/sampler_operations.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/sampler_operations.ts @@ -9,7 +9,7 @@ import { BalancerPoolsCache, computeBalancerBuyQuote, computeBalancerSellQuote } import { BancorService } from './bancor_service'; import { MAINNET_SUSHI_SWAP_ROUTER, MAX_UINT256, NULL_BYTES, ZERO_AMOUNT } from './constants'; import { CreamPoolsCache } from './cream_utils'; -import { getCurveInfosForPair, getSwerveInfosForPair } from './curve_utils'; +import { getCurveInfosForPair, getSnowSwapInfosForPair, getSwerveInfosForPair } from './curve_utils'; import { getKyberReserveIdsForPair } from './kyber_utils'; import { getMultiBridgeIntermediateToken } from './multibridge_utils'; import { getIntermediateTokens } from './multihop_utils'; @@ -30,6 +30,8 @@ import { MooniswapFillData, MultiBridgeFillData, MultiHopFillData, + SnowSwapFillData, + SnowSwapInfo, SourceQuoteOperation, SushiSwapFillData, SwerveFillData, @@ -407,6 +409,62 @@ export class SamplerOperations { }); } + public getSnowSwapSellQuotes( + pool: SnowSwapInfo, + fromTokenIdx: number, + toTokenIdx: number, + takerFillAmounts: BigNumber[], + ): SourceQuoteOperation { + 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 { + 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( poolAddress: string, makerToken: string, @@ -1041,6 +1099,15 @@ export class SamplerOperations { takerFillAmounts, ), ); + case ERC20BridgeSource.SnowSwap: + return getSnowSwapInfosForPair(takerToken, makerToken).map(snowswap => + this.getSnowSwapSellQuotes( + snowswap, + snowswap.tokens.indexOf(takerToken), + snowswap.tokens.indexOf(makerToken), + takerFillAmounts, + ), + ); case ERC20BridgeSource.LiquidityProvider: if (liquidityProviderRegistryAddress === undefined) { throw new Error( @@ -1164,6 +1231,15 @@ export class SamplerOperations { makerFillAmounts, ), ); + case ERC20BridgeSource.SnowSwap: + return getSnowSwapInfosForPair(takerToken, makerToken).map(snowswap => + this.getSnowSwapBuyQuotes( + snowswap, + snowswap.tokens.indexOf(takerToken), + snowswap.tokens.indexOf(makerToken), + makerFillAmounts, + ), + ); case ERC20BridgeSource.LiquidityProvider: if (liquidityProviderRegistryAddress === undefined) { throw new Error( diff --git a/packages/asset-swapper/src/utils/market_operation_utils/types.ts b/packages/asset-swapper/src/utils/market_operation_utils/types.ts index 5a7ebc9dc4..0fa88b6142 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/types.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/types.ts @@ -44,6 +44,7 @@ export enum ERC20BridgeSource { MultiHop = 'MultiHop', Shell = 'Shell', Swerve = 'Swerve', + SnowSwap = 'SnowSwap', SushiSwap = 'SushiSwap', Dodo = 'DODO', } @@ -75,6 +76,7 @@ export interface CurveInfo { } export interface SwerveInfo extends CurveInfo {} +export interface SnowSwapInfo extends CurveInfo {} // Internal `fillData` field for `Fill` objects. export interface FillData {} @@ -101,6 +103,12 @@ export interface SwerveFillData extends FillData { pool: SwerveInfo; } +export interface SnowSwapFillData extends FillData { + fromTokenIdx: number; + toTokenIdx: number; + pool: SnowSwapInfo; +} + export interface BalancerFillData extends FillData { poolAddress: string; } diff --git a/packages/asset-swapper/test/market_operation_utils_test.ts b/packages/asset-swapper/test/market_operation_utils_test.ts index 8e54b748fa..80a32aa447 100644 --- a/packages/asset-swapper/test/market_operation_utils_test.ts +++ b/packages/asset-swapper/test/market_operation_utils_test.ts @@ -43,6 +43,7 @@ const DEFAULT_EXCLUDED = [ ERC20BridgeSource.Mooniswap, ERC20BridgeSource.Bancor, ERC20BridgeSource.Swerve, + ERC20BridgeSource.SnowSwap, ERC20BridgeSource.SushiSwap, ERC20BridgeSource.MultiHop, ERC20BridgeSource.Shell, @@ -284,6 +285,7 @@ describe('MarketOperationUtils tests', () => { [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), @@ -329,6 +331,17 @@ describe('MarketOperationUtils tests', () => { fromTokenIdx: 0, 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.SushiSwap]: { tokenAddressPath: [] }, [ERC20BridgeSource.Mooniswap]: { poolAddress: randomAddress() }, From f783625d60d2eea2ad817575cb221fc1b0a28187 Mon Sep 17 00:00:00 2001 From: Romain Butteaud Date: Tue, 13 Oct 2020 19:27:23 -0700 Subject: [PATCH 2/7] feat: adding yVaultUSDUnderlying --- .../utils/market_operation_utils/constants.ts | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/packages/asset-swapper/src/utils/market_operation_utils/constants.ts b/packages/asset-swapper/src/utils/market_operation_utils/constants.ts index 28d5bfa1e8..11a7e1fd5c 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/constants.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/constants.ts @@ -186,24 +186,40 @@ export const MAINNET_SWERVE_INFOS: { [name: string]: CurveInfo } = { }, }; export const MAINNET_SNOWSWAP_INFOS: { [name: string]: CurveInfo } = { - yVaultCurve: { - exchangeFunctionSelector: CurveFunctionSelectors.exchange, - sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, - buyQuoteFunctionSelector: CurveFunctionSelectors.None, - poolAddress: '0xBf7CCD6C446acfcc5dF023043f2167B62E81899b', - tokens: [ - '0x5dbcf33d8c2e976c6b560249878e6f1491bca25c', // yUSD - '0x2994529c0652d127b7842094103715ec5299bbed', // ybCRV - ], - }, - yVaultUSD: { - exchangeFunctionSelector: CurveFunctionSelectors.exchange, + // yVaultCurve: { + // exchangeFunctionSelector: CurveFunctionSelectors.exchange, + // sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy, + // buyQuoteFunctionSelector: CurveFunctionSelectors.None, + // poolAddress: '0xBf7CCD6C446acfcc5dF023043f2167B62E81899b', + // tokens: [ + // '0x5dbcf33d8c2e976c6b560249878e6f1491bca25c', // yUSD + // '0x2994529c0652d127b7842094103715ec5299bbed', // ybCRV + // ], + // }, + yVaultUSDUnderlying: { + exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, buyQuoteFunctionSelector: CurveFunctionSelectors.None, poolAddress: '0x4571753311E37dDb44faA8Fb78a6dF9a6E3c6C0B', tokens: [ - '0x597ad1e0c13bfe8025993d9e79c69e1c0233522e', // yUSDC + // underlying tokens, in SnowSwaps order + '0x6B175474E89094C44Da98b954EedeAC495271d0F', // DAI + '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC + '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDT + '0x0000000000085d4780B73119b644AE5ecd22b376', // TUSD + ], + }, + yVaultUSD: { + // Note we're not trading the underlying but the y representation + // so we use `exchange` and `get_dy` + exchangeFunctionSelector: CurveFunctionSelectors.exchange, + sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy, + buyQuoteFunctionSelector: CurveFunctionSelectors.None, + poolAddress: '0x4571753311E37dDb44faA8Fb78a6dF9a6E3c6C0B', + tokens: [ + // the "non" underlying tokens, in the SnowSwap defined order '0xacd43e627e64355f1861cec6d3a6688b31a6f952', // yDAI + '0x597ad1e0c13bfe8025993d9e79c69e1c0233522e', // yUSDC '0x2f08119c6f07c006695e079aafc638b8789faf18', // yUSDT '0x37d19d1c4e1fa9dc47bd1ea12f742a0887eda74a', // yTUSD ], From 3182c12b4d4f9127c13a901720a1d0f315426e3c Mon Sep 17 00:00:00 2001 From: Romain Butteaud Date: Wed, 14 Oct 2020 14:08:02 -0700 Subject: [PATCH 3/7] feat: use pool attribute instead of curve for all Curve like pools --- .../utils/market_operation_utils/constants.ts | 58 +++++++++---------- .../utils/market_operation_utils/orders.ts | 4 +- .../sampler_operations.ts | 52 ++++++++--------- .../src/utils/market_operation_utils/types.ts | 2 +- .../test/market_operation_utils_test.ts | 2 +- 5 files changed, 59 insertions(+), 59 deletions(-) diff --git a/packages/asset-swapper/src/utils/market_operation_utils/constants.ts b/packages/asset-swapper/src/utils/market_operation_utils/constants.ts index 11a7e1fd5c..dc7a707551 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/constants.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/constants.ts @@ -174,9 +174,9 @@ export const MAINNET_CURVE_INFOS: { [name: string]: CurveInfo } = { export const MAINNET_SWERVE_INFOS: { [name: string]: CurveInfo } = { swUSD: { exchangeFunctionSelector: CurveFunctionSelectors.exchange, - sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, + sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy, buyQuoteFunctionSelector: CurveFunctionSelectors.None, - poolAddress: '0x329239599afB305DA0A2eC69c58F8a6697F9F88d', + poolAddress: '0x329239599afb305da0a2ec69c58f8a6697f9f88d', tokens: [ '0x6b175474e89094c44da98b954eedeac495271d0f', '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', @@ -186,36 +186,36 @@ 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.None, - // poolAddress: '0xBf7CCD6C446acfcc5dF023043f2167B62E81899b', - // tokens: [ - // '0x5dbcf33d8c2e976c6b560249878e6f1491bca25c', // yUSD - // '0x2994529c0652d127b7842094103715ec5299bbed', // ybCRV - // ], - // }, - yVaultUSDUnderlying: { - exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, - sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, - buyQuoteFunctionSelector: CurveFunctionSelectors.None, - poolAddress: '0x4571753311E37dDb44faA8Fb78a6dF9a6E3c6C0B', - tokens: [ - // underlying tokens, in SnowSwaps order - '0x6B175474E89094C44Da98b954EedeAC495271d0F', // DAI - '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC - '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDT - '0x0000000000085d4780B73119b644AE5ecd22b376', // TUSD - ], - }, - yVaultUSD: { - // Note we're not trading the underlying but the y representation - // so we use `exchange` and `get_dy` + yVaultCurve: { exchangeFunctionSelector: CurveFunctionSelectors.exchange, sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy, buyQuoteFunctionSelector: CurveFunctionSelectors.None, - poolAddress: '0x4571753311E37dDb44faA8Fb78a6dF9a6E3c6C0B', + poolAddress: '0xBf7CCD6C446acfcc5dF023043f2167B62E81899b', + tokens: [ + '0x5dbcf33d8c2e976c6b560249878e6f1491bca25c', // yUSD + '0x2994529c0652d127b7842094103715ec5299bbed', // ybCRV + ], + }, + // yVaultUSDUnderlying: { + // exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, + // sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, + // buyQuoteFunctionSelector: CurveFunctionSelectors.None, + // poolAddress: '0x4571753311e37ddb44faa8fb78a6df9a6e3c6c0b', + // tokens: [ + // // underlying tokens, in SnowSwaps order + // '0x6b175474e89094c44da98b954eedeac495271d0f', // DAI + // '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // USDC + // '0xdac17f958d2ee523a2206206994597c13d831ec7', // USDT + // '0x0000000000085d4780b73119b644ae5ecd22b376', // TUSD + // ], + // }, + yVaultUSD: { + // Note we're not trading the underlying but the y representation + // so we use `exchange` and `get_dy` + exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, + sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, + buyQuoteFunctionSelector: CurveFunctionSelectors.None, + poolAddress: '0x4571753311e37ddb44faa8fb78a6df9a6e3c6c0b', tokens: [ // the "non" underlying tokens, in the SnowSwap defined order '0xacd43e627e64355f1861cec6d3a6688b31a6f952', // yDAI diff --git a/packages/asset-swapper/src/utils/market_operation_utils/orders.ts b/packages/asset-swapper/src/utils/market_operation_utils/orders.ts index efadab35ff..d78c066e1a 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/orders.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/orders.ts @@ -216,8 +216,8 @@ export function createBridgeOrder( makerToken, bridgeAddress, createCurveBridgeData( - curveFillData.curve.poolAddress, - curveFillData.curve.exchangeFunctionSelector, + curveFillData.pool.poolAddress, + curveFillData.pool.exchangeFunctionSelector, takerToken, curveFillData.fromTokenIdx, curveFillData.toTokenIdx, diff --git a/packages/asset-swapper/src/utils/market_operation_utils/sampler_operations.ts b/packages/asset-swapper/src/utils/market_operation_utils/sampler_operations.ts index a38c97aa00..583a3965f4 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/sampler_operations.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/sampler_operations.ts @@ -298,7 +298,7 @@ export class SamplerOperations { } public getCurveSellQuotes( - curve: CurveInfo, + pool: CurveInfo, fromTokenIdx: number, toTokenIdx: number, takerFillAmounts: BigNumber[], @@ -306,7 +306,7 @@ export class SamplerOperations { return new SamplerContractOperation({ source: ERC20BridgeSource.Curve, fillData: { - curve, + pool, fromTokenIdx, toTokenIdx, }, @@ -314,9 +314,9 @@ export class SamplerOperations { function: this._samplerContract.sampleSellsFromCurve, params: [ { - poolAddress: curve.poolAddress, - sellQuoteFunctionSelector: curve.sellQuoteFunctionSelector, - buyQuoteFunctionSelector: curve.buyQuoteFunctionSelector, + poolAddress: pool.poolAddress, + sellQuoteFunctionSelector: pool.sellQuoteFunctionSelector, + buyQuoteFunctionSelector: pool.buyQuoteFunctionSelector, }, new BigNumber(fromTokenIdx), new BigNumber(toTokenIdx), @@ -326,7 +326,7 @@ export class SamplerOperations { } public getCurveBuyQuotes( - curve: CurveInfo, + pool: CurveInfo, fromTokenIdx: number, toTokenIdx: number, makerFillAmounts: BigNumber[], @@ -334,7 +334,7 @@ export class SamplerOperations { return new SamplerContractOperation({ source: ERC20BridgeSource.Curve, fillData: { - curve, + pool, fromTokenIdx, toTokenIdx, }, @@ -342,9 +342,9 @@ export class SamplerOperations { function: this._samplerContract.sampleBuysFromCurve, params: [ { - poolAddress: curve.poolAddress, - sellQuoteFunctionSelector: curve.sellQuoteFunctionSelector, - buyQuoteFunctionSelector: curve.buyQuoteFunctionSelector, + poolAddress: pool.poolAddress, + sellQuoteFunctionSelector: pool.sellQuoteFunctionSelector, + buyQuoteFunctionSelector: pool.buyQuoteFunctionSelector, }, new BigNumber(fromTokenIdx), new BigNumber(toTokenIdx), @@ -1082,11 +1082,11 @@ export class SamplerOperations { this.getKyberSellQuotes(reserveId, makerToken, takerToken, takerFillAmounts), ); case ERC20BridgeSource.Curve: - return getCurveInfosForPair(takerToken, makerToken).map(curve => + return getCurveInfosForPair(takerToken, makerToken).map(pool => this.getCurveSellQuotes( - curve, - curve.tokens.indexOf(takerToken), - curve.tokens.indexOf(makerToken), + pool, + pool.tokens.indexOf(takerToken), + pool.tokens.indexOf(makerToken), takerFillAmounts, ), ); @@ -1100,11 +1100,11 @@ export class SamplerOperations { ), ); case ERC20BridgeSource.SnowSwap: - return getSnowSwapInfosForPair(takerToken, makerToken).map(snowswap => + return getSnowSwapInfosForPair(takerToken, makerToken).map(pool => this.getSnowSwapSellQuotes( - snowswap, - snowswap.tokens.indexOf(takerToken), - snowswap.tokens.indexOf(makerToken), + pool, + pool.tokens.indexOf(takerToken), + pool.tokens.indexOf(makerToken), takerFillAmounts, ), ); @@ -1214,11 +1214,11 @@ export class SamplerOperations { this.getKyberBuyQuotes(reserveId, makerToken, takerToken, makerFillAmounts), ); case ERC20BridgeSource.Curve: - return getCurveInfosForPair(takerToken, makerToken).map(curve => + return getCurveInfosForPair(takerToken, makerToken).map(pool => this.getCurveBuyQuotes( - curve, - curve.tokens.indexOf(takerToken), - curve.tokens.indexOf(makerToken), + pool, + pool.tokens.indexOf(takerToken), + pool.tokens.indexOf(makerToken), makerFillAmounts, ), ); @@ -1232,11 +1232,11 @@ export class SamplerOperations { ), ); case ERC20BridgeSource.SnowSwap: - return getSnowSwapInfosForPair(takerToken, makerToken).map(snowswap => + return getSnowSwapInfosForPair(takerToken, makerToken).map(pool => this.getSnowSwapBuyQuotes( - snowswap, - snowswap.tokens.indexOf(takerToken), - snowswap.tokens.indexOf(makerToken), + pool, + pool.tokens.indexOf(takerToken), + pool.tokens.indexOf(makerToken), makerFillAmounts, ), ); diff --git a/packages/asset-swapper/src/utils/market_operation_utils/types.ts b/packages/asset-swapper/src/utils/market_operation_utils/types.ts index 0fa88b6142..601eac2936 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/types.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/types.ts @@ -94,7 +94,7 @@ export interface NativeFillData extends FillData { export interface CurveFillData extends FillData { fromTokenIdx: number; toTokenIdx: number; - curve: CurveInfo; + pool: CurveInfo; } export interface SwerveFillData extends FillData { diff --git a/packages/asset-swapper/test/market_operation_utils_test.ts b/packages/asset-swapper/test/market_operation_utils_test.ts index 80a32aa447..3628329c81 100644 --- a/packages/asset-swapper/test/market_operation_utils_test.ts +++ b/packages/asset-swapper/test/market_operation_utils_test.ts @@ -310,7 +310,7 @@ describe('MarketOperationUtils tests', () => { [ERC20BridgeSource.Bancor]: { path: [], networkAddress: randomAddress() }, [ERC20BridgeSource.Kyber]: { hint: '0x', reserveId: '0x' }, [ERC20BridgeSource.Curve]: { - curve: { + pool: { poolAddress: randomAddress(), tokens: [TAKER_TOKEN, MAKER_TOKEN], exchangeFunctionSelector: hexUtils.random(4), From b2dfd8740c08976042ee7928be774c31e9035e2e Mon Sep 17 00:00:00 2001 From: Romain Butteaud Date: Wed, 14 Oct 2020 17:22:20 -0700 Subject: [PATCH 4/7] feat: fix CURVE_CALL_GAS and SnowSwap pool addresses --- .../contracts/src/CurveSampler.sol | 2 +- .../utils/market_operation_utils/constants.ts | 46 +++++++++++-------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/packages/asset-swapper/contracts/src/CurveSampler.sol b/packages/asset-swapper/contracts/src/CurveSampler.sol index 62e4d611e0..c663dd519d 100644 --- a/packages/asset-swapper/contracts/src/CurveSampler.sol +++ b/packages/asset-swapper/contracts/src/CurveSampler.sol @@ -37,7 +37,7 @@ contract CurveSampler is /// @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. - uint256 constant private CURVE_CALL_GAS = 600e3; // 600k + uint256 constant private CURVE_CALL_GAS = 600e3; // Was 600k for Curve but SnowSwap is using 1500k+ /// @dev Sample sell quotes from Curve. /// @param curveInfo Curve information specific to this token pair. diff --git a/packages/asset-swapper/src/utils/market_operation_utils/constants.ts b/packages/asset-swapper/src/utils/market_operation_utils/constants.ts index dc7a707551..f73e96271e 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/constants.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/constants.ts @@ -189,41 +189,47 @@ export const MAINNET_SNOWSWAP_INFOS: { [name: string]: CurveInfo } = { yVaultCurve: { exchangeFunctionSelector: CurveFunctionSelectors.exchange, sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy, - buyQuoteFunctionSelector: CurveFunctionSelectors.None, - poolAddress: '0xBf7CCD6C446acfcc5dF023043f2167B62E81899b', + buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx, + poolAddress: '0xbf7ccd6c446acfcc5df023043f2167b62e81899b', tokens: [ '0x5dbcf33d8c2e976c6b560249878e6f1491bca25c', // yUSD '0x2994529c0652d127b7842094103715ec5299bbed', // ybCRV ], }, - // yVaultUSDUnderlying: { - // exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, - // sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, - // buyQuoteFunctionSelector: CurveFunctionSelectors.None, - // poolAddress: '0x4571753311e37ddb44faa8fb78a6df9a6e3c6c0b', - // tokens: [ - // // underlying tokens, in SnowSwaps order - // '0x6b175474e89094c44da98b954eedeac495271d0f', // DAI - // '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // USDC - // '0xdac17f958d2ee523a2206206994597c13d831ec7', // USDT - // '0x0000000000085d4780b73119b644ae5ecd22b376', // TUSD - // ], - // }, - yVaultUSD: { - // Note we're not trading the underlying but the y representation - // so we use `exchange` and `get_dy` + yVaultCurveUnderlying: { exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, - buyQuoteFunctionSelector: CurveFunctionSelectors.None, + 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: [ - // the "non" underlying tokens, in the SnowSwap defined order '0xacd43e627e64355f1861cec6d3a6688b31a6f952', // yDAI '0x597ad1e0c13bfe8025993d9e79c69e1c0233522e', // yUSDC '0x2f08119c6f07c006695e079aafc638b8789faf18', // yUSDT '0x37d19d1c4e1fa9dc47bd1ea12f742a0887eda74a', // yTUSD ], }, + 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 } = { From 03bc15fbdffb40daa51439d1c4b3e170f80c7acf Mon Sep 17 00:00:00 2001 From: Romain Butteaud Date: Wed, 14 Oct 2020 20:18:40 -0700 Subject: [PATCH 5/7] fix: add _target comment for Swerve pool --- .../asset-swapper/src/utils/market_operation_utils/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/asset-swapper/src/utils/market_operation_utils/constants.ts b/packages/asset-swapper/src/utils/market_operation_utils/constants.ts index f73e96271e..521756ba51 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/constants.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/constants.ts @@ -176,7 +176,7 @@ export const MAINNET_SWERVE_INFOS: { [name: string]: CurveInfo } = { exchangeFunctionSelector: CurveFunctionSelectors.exchange, sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy, buyQuoteFunctionSelector: CurveFunctionSelectors.None, - poolAddress: '0x329239599afb305da0a2ec69c58f8a6697f9f88d', + poolAddress: '0x329239599afb305da0a2ec69c58f8a6697f9f88d', // _target: 0xa5407eae9ba41422680e2e00537571bcc53efbfd tokens: [ '0x6b175474e89094c44da98b954eedeac495271d0f', '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', From b79855677494e45921cd04040e88038d81c9df41 Mon Sep 17 00:00:00 2001 From: Romain Butteaud Date: Thu, 15 Oct 2020 16:46:14 -0700 Subject: [PATCH 6/7] feat: adjusting CURVE_CALL_GAS for SnowSwap, disabling yVaultUSDUnderlying pool for underlying tokens --- .../contracts/src/CurveSampler.sol | 2 +- .../utils/market_operation_utils/constants.ts | 25 ++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/asset-swapper/contracts/src/CurveSampler.sol b/packages/asset-swapper/contracts/src/CurveSampler.sol index c663dd519d..36b1de99db 100644 --- a/packages/asset-swapper/contracts/src/CurveSampler.sol +++ b/packages/asset-swapper/contracts/src/CurveSampler.sol @@ -37,7 +37,7 @@ contract CurveSampler is /// @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. - uint256 constant private CURVE_CALL_GAS = 600e3; // Was 600k for Curve but SnowSwap is using 1500k+ + uint256 constant private CURVE_CALL_GAS = 2000e3; // Was 600k for Curve but SnowSwap is using 1500k+ /// @dev Sample sell quotes from Curve. /// @param curveInfo Curve information specific to this token pair. diff --git a/packages/asset-swapper/src/utils/market_operation_utils/constants.ts b/packages/asset-swapper/src/utils/market_operation_utils/constants.ts index 521756ba51..b17aaa5b71 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/constants.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/constants.ts @@ -218,18 +218,19 @@ export const MAINNET_SNOWSWAP_INFOS: { [name: string]: CurveInfo } = { '0x37d19d1c4e1fa9dc47bd1ea12f742a0887eda74a', // yTUSD ], }, - 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 - ], - }, + // 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 } = { From 649202f1c48c2e72a4e7f3a93ec0fad5eae2e1ef Mon Sep 17 00:00:00 2001 From: Romain Butteaud Date: Mon, 19 Oct 2020 14:59:18 -0700 Subject: [PATCH 7/7] fix: prettier --- .../src/utils/market_operation_utils/curve_utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/asset-swapper/src/utils/market_operation_utils/curve_utils.ts b/packages/asset-swapper/src/utils/market_operation_utils/curve_utils.ts index 84bc42df9b..f84dc86c15 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/curve_utils.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/curve_utils.ts @@ -12,4 +12,4 @@ export function getSwerveInfosForPair(takerToken: string, makerToken: string): S export function getSnowSwapInfosForPair(takerToken: string, makerToken: string): SnowSwapInfo[] { return Object.values(MAINNET_SNOWSWAP_INFOS).filter(c => [makerToken, takerToken].every(t => c.tokens.includes(t))); -} \ No newline at end of file +}