From 37aae134ab4f252c01d1209eba53f238852c33eb Mon Sep 17 00:00:00 2001 From: Romain Butteaud Date: Thu, 5 Nov 2020 15:27:45 -0800 Subject: [PATCH] feat: adding Curve pools: PAX, hBTC, metapools: gUSD, hUSD, USDn, mUSD, tBTC (#26) * feat: adding Curve pools: PAX, hbtc, metapools: gusd, husd, usdn, musd, tbtc * feat: CHANGELOG * fix: bad import * fix: curve_y address downcase, use POOLS addresses for names * feat: add metaToken attribute to disable metapools for non-metaTokens in Curve * fix: CHANGELOG --- packages/asset-swapper/CHANGELOG.json | 4 + .../utils/market_operation_utils/constants.ts | 175 +++++++++++++----- .../market_operation_utils/curve_utils.ts | 24 ++- .../src/utils/market_operation_utils/types.ts | 1 + 4 files changed, 156 insertions(+), 48 deletions(-) diff --git a/packages/asset-swapper/CHANGELOG.json b/packages/asset-swapper/CHANGELOG.json index 6549f53303..5f349de31b 100644 --- a/packages/asset-swapper/CHANGELOG.json +++ b/packages/asset-swapper/CHANGELOG.json @@ -5,6 +5,10 @@ "changes": [ { "note": "Dependencies updated" + }, + { + "note": "adding Curve pools: PAX, hBTC, metapools: gUSD, hUSD, USDn, mUSD, tBTC", + "pr": 26 } ] }, 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 c614f28171..c54cda9226 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/constants.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/constants.ts @@ -98,29 +98,60 @@ export const TOKENS = { USDC: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', USDT: '0xdac17f958d2ee523a2206206994597c13d831ec7', sUSD: '0x57ab1ec28d129707052df4df418d58a2d46d5f51', + BUSD: '0x4fabb145d64652a948d72533023f6e7a623c7c53', TUSD: '0x0000000000085d4780b73119b644ae5ecd22b376', + PAX: '0x8e870d67f660d95d5be530380d0ec0bd388289e1', + GUSD: '0x056fd409e1d7a124bd7017459dfea2f387b6d5cd', + HUSD: '0xdf574c24545e5ffecb9a659c229253d4111d87e1', + mUSD: '0xe2f2a5c287993345a840db3b0845fbc70f5935a5', + USDN: '0x674c6ad92fd080e4004b2312b45f796a192d27a0', // Bitcoins WBTC: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', RenBTC: '0xeb4c2781e4eba804ce9a9803c67d0893436bb27d', sBTC: '0xfe18be6b3bd88a2d2a7f928d00292e7a9963cfc6', + tBTC: '0x8daebade922df735c38c80c7ebd708af50815faa', + hBTC: '0x0316eb71485b0ab14103307bf65a021042c6d380', // Other MKR: '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2', }; +export const POOLS = { + // following the same order in curve.fi: + curve_compound: '0xa2b47e3d5c44877cca798226b7b8118f9bfb7a56', + // curve_USDT: '0x52ea46506b9cc5ef470c5bf89f17dc28bb35d85c', + curve_PAX: '0x06364f10b501e868329afbc005b3492902d6c763', + curve_y: '0x45f783cce6b7ff23b2ab2d70e416cdb7d6055f51', + curve_BUSD: '0x79a8c46dea5ada233abaffd40f3a0a2b1e5a4f27', + curve_sUSD: '0xa5407eae9ba41422680e2e00537571bcc53efbfd', + curve_renBTC: '0x93054188d876f558f4a66b2ef1d97d16edf0895b', + curve_sBTC: '0x7fc77b5c7614e1533320ea6ddc2eb61fa00a9714', + curve_HBTC: '0x4ca9b3063ec5866a4b82e437059d2c43d1be596f', + curve_TRI: '0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7', + curve_GUSD: '0x4f062658eaaf2c1ccf8c8e36d6824cdf41167956', + curve_HUSD: '0x3ef6a01a0f81d6046290f3e2a8c5b843e738e604', + // 12.usdk is dead + curve_USDN: '0x0f9cb53ebe405d49a0bbdbd291a65ff571bc83e1', + // 14.linkusd is dead + curve_mUSD: '0x8474ddbe98f5aa3179b3b3f5942d724afcdec9f6', + // 16.rsv is dead + curve_tBTC: '0xc25099792e9349c7dd09759744ea681c7de2cb66', +}; + /** * Mainnet Curve configuration * The tokens are in order of their index, which each curve defines * I.e DaiUsdc curve has DAI as index 0 and USDC as index 1 */ export const MAINNET_CURVE_INFOS: { [name: string]: CurveInfo } = { - DaiUsdc: { + [POOLS.curve_compound]: { exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx_underlying, - poolAddress: '0xa2b47e3d5c44877cca798226b7b8118f9bfb7a56', + poolAddress: POOLS.curve_compound, tokens: [TOKENS.DAI, TOKENS.USDC], + metaToken: undefined, }, - // DaiUsdcUsdt: { + // USDT: { // exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, // sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, // buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx_underlying, @@ -131,53 +162,110 @@ export const MAINNET_CURVE_INFOS: { [name: string]: CurveInfo } = { // TOKENS.USDT, // ], // }, - DaiUsdcUsdtTusd: { + [POOLS.curve_PAX]: { + exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, + sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, + buyQuoteFunctionSelector: CurveFunctionSelectors.None, + poolAddress: POOLS.curve_PAX, + tokens: [TOKENS.DAI, TOKENS.USDC, TOKENS.USDT, TOKENS.PAX], + metaToken: undefined, + }, + [POOLS.curve_y]: { exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx_underlying, - poolAddress: '0x45f783cce6b7ff23b2ab2d70e416cdb7d6055f51', + poolAddress: POOLS.curve_y, tokens: [TOKENS.DAI, TOKENS.USDC, TOKENS.USDT, TOKENS.TUSD], + metaToken: undefined, }, - // Looks like it's dying. - DaiUsdcUsdtBusd: { + [POOLS.curve_BUSD]: { exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx_underlying, - poolAddress: '0x79a8c46dea5ada233abaffd40f3a0a2b1e5a4f27', - tokens: [ - TOKENS.DAI, - TOKENS.USDC, - TOKENS.USDT, - '0x4fabb145d64652a948d72533023f6e7a623c7c53', // bUSD - ], + poolAddress: POOLS.curve_BUSD, + tokens: [TOKENS.DAI, TOKENS.USDC, TOKENS.USDT, TOKENS.BUSD], + metaToken: undefined, }, - DaiUsdcUsdtSusd: { + [POOLS.curve_sUSD]: { exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, buyQuoteFunctionSelector: CurveFunctionSelectors.None, - poolAddress: '0xa5407eae9ba41422680e2e00537571bcc53efbfd', + poolAddress: POOLS.curve_sUSD, tokens: [TOKENS.DAI, TOKENS.USDC, TOKENS.USDT, TOKENS.sUSD], + metaToken: undefined, }, - RenbtcWbtc: { + [POOLS.curve_renBTC]: { exchangeFunctionSelector: CurveFunctionSelectors.exchange, sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy, buyQuoteFunctionSelector: CurveFunctionSelectors.None, - poolAddress: '0x93054188d876f558f4a66b2ef1d97d16edf0895b', + poolAddress: POOLS.curve_renBTC, tokens: [TOKENS.RenBTC, TOKENS.WBTC], + metaToken: undefined, }, - RenbtcWbtcSbtc: { + [POOLS.curve_sBTC]: { exchangeFunctionSelector: CurveFunctionSelectors.exchange, sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy, buyQuoteFunctionSelector: CurveFunctionSelectors.None, - poolAddress: '0x7fc77b5c7614e1533320ea6ddc2eb61fa00a9714', + poolAddress: POOLS.curve_sBTC, tokens: [TOKENS.RenBTC, TOKENS.WBTC, TOKENS.sBTC], + metaToken: undefined, }, - TriPool: { + [POOLS.curve_HBTC]: { exchangeFunctionSelector: CurveFunctionSelectors.exchange, sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy, buyQuoteFunctionSelector: CurveFunctionSelectors.None, - poolAddress: '0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7', + poolAddress: POOLS.curve_HBTC, + tokens: [TOKENS.hBTC, TOKENS.WBTC], + metaToken: undefined, + }, + [POOLS.curve_TRI]: { + exchangeFunctionSelector: CurveFunctionSelectors.exchange, + sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy, + buyQuoteFunctionSelector: CurveFunctionSelectors.None, + poolAddress: POOLS.curve_TRI, tokens: [TOKENS.DAI, TOKENS.USDC, TOKENS.USDT], + metaToken: undefined, + }, + // Metapools + [POOLS.curve_GUSD]: { + exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, + sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, + buyQuoteFunctionSelector: CurveFunctionSelectors.None, + poolAddress: POOLS.curve_GUSD, + tokens: [TOKENS.GUSD, TOKENS.DAI, TOKENS.USDC, TOKENS.USDT], + metaToken: TOKENS.GUSD, + }, + [POOLS.curve_HUSD]: { + exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, + sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, + buyQuoteFunctionSelector: CurveFunctionSelectors.None, + poolAddress: POOLS.curve_HUSD, + tokens: [TOKENS.HUSD, TOKENS.DAI, TOKENS.USDC, TOKENS.USDT], + metaToken: TOKENS.HUSD, + }, + [POOLS.curve_USDN]: { + exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, + sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, + buyQuoteFunctionSelector: CurveFunctionSelectors.None, + poolAddress: POOLS.curve_USDN, + tokens: [TOKENS.USDN, TOKENS.DAI, TOKENS.USDC, TOKENS.USDT], + metaToken: TOKENS.USDN, + }, + [POOLS.curve_mUSD]: { + exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, + sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, + buyQuoteFunctionSelector: CurveFunctionSelectors.None, + poolAddress: POOLS.curve_mUSD, + tokens: [TOKENS.mUSD, TOKENS.DAI, TOKENS.USDC, TOKENS.USDT], + metaToken: TOKENS.mUSD, + }, + [POOLS.curve_tBTC]: { + exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, + sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, + buyQuoteFunctionSelector: CurveFunctionSelectors.None, + poolAddress: POOLS.curve_tBTC, + tokens: [TOKENS.tBTC, TOKENS.RenBTC, TOKENS.WBTC, TOKENS.sBTC], + metaToken: TOKENS.tBTC, }, }; @@ -188,6 +276,7 @@ export const MAINNET_SWERVE_INFOS: { [name: string]: CurveInfo } = { buyQuoteFunctionSelector: CurveFunctionSelectors.None, poolAddress: '0x329239599afb305da0a2ec69c58f8a6697f9f88d', // _target: 0xa5407eae9ba41422680e2e00537571bcc53efbfd tokens: [TOKENS.DAI, TOKENS.USDC, TOKENS.USDT, TOKENS.TUSD], + metaToken: undefined, }, }; @@ -201,6 +290,7 @@ export const MAINNET_SNOWSWAP_INFOS: { [name: string]: CurveInfo } = { '0x5dbcf33d8c2e976c6b560249878e6f1491bca25c', // yUSD '0x2994529c0652d127b7842094103715ec5299bbed', // ybCRV ], + metaToken: undefined, }, yVaultCurveUnderlying: { exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, @@ -211,6 +301,7 @@ export const MAINNET_SNOWSWAP_INFOS: { [name: string]: CurveInfo } = { '0xdf5e0e81dff6faf3a7e52ba697820c5e32d806a8', // yCRV '0x3b3ac5386837dc563660fb6a0937dfaa5924333b', // bCRV ], + metaToken: undefined, }, yVaultUSD: { exchangeFunctionSelector: CurveFunctionSelectors.exchange, @@ -223,20 +314,8 @@ export const MAINNET_SNOWSWAP_INFOS: { [name: string]: CurveInfo } = { '0x2f08119c6f07c006695e079aafc638b8789faf18', // yUSDT '0x37d19d1c4e1fa9dc47bd1ea12f742a0887eda74a', // yTUSD ], + metaToken: undefined, }, - // 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: [ - // TOKENS.DAI, - // TOKENS.USDC, - // TOKENS.USDT, - // TOKENS.TUSD, - // ], - // }, }; export const MAINNET_KYBER_RESERVE_IDS: { [name: string]: string } = { @@ -361,19 +440,25 @@ export const DEFAULT_GAS_SCHEDULE: Required = { [ERC20BridgeSource.Curve]: fillData => { const poolAddress = (fillData as CurveFillData).pool.poolAddress.toLowerCase(); switch (poolAddress) { - case '0xa5407eae9ba41422680e2e00537571bcc53efbfd': - case '0x93054188d876f558f4a66b2ef1d97d16edf0895b': - case '0x7fc77b5c7614e1533320ea6ddc2eb61fa00a9714': - case '0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7': + case POOLS.curve_renBTC: + case POOLS.curve_sBTC: + case POOLS.curve_sUSD: + case POOLS.curve_HBTC: + case POOLS.curve_TRI: return 150e3; - case '0xa2b47e3d5c44877cca798226b7b8118f9bfb7a56': + case POOLS.curve_compound: return 750e3; - case '0x45f783cce6b7ff23b2ab2d70e416cdb7d6055f51': + case POOLS.curve_PAX: + case POOLS.curve_y: + case POOLS.curve_BUSD: return 850e3; - case '0x79a8c46dea5ada233abaffd40f3a0a2b1e5a4f27': - return 1e6; - case '0x52ea46506b9cc5ef470c5bf89f17dc28bb35d85c': - return 600e3; + // Metapools + case POOLS.curve_GUSD: + case POOLS.curve_HUSD: + case POOLS.curve_USDN: + case POOLS.curve_mUSD: + case POOLS.curve_tBTC: + return 650e3; default: throw new Error(`Unrecognized Curve address: ${poolAddress}`); } 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 f84dc86c15..ed12d0830e 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 @@ -3,13 +3,31 @@ import { CurveInfo, SnowSwapInfo, SwerveInfo } from './types'; // tslint:disable completed-docs export function getCurveInfosForPair(takerToken: string, makerToken: string): CurveInfo[] { - return Object.values(MAINNET_CURVE_INFOS).filter(c => [makerToken, takerToken].every(t => c.tokens.includes(t))); + return Object.values(MAINNET_CURVE_INFOS).filter(c => + [makerToken, takerToken].every( + t => + (c.tokens.includes(t) && c.metaToken === undefined) || + (c.tokens.includes(t) && c.metaToken !== undefined && [makerToken, takerToken].includes(c.metaToken)), + ), + ); } 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) && c.metaToken === undefined) || + (c.tokens.includes(t) && c.metaToken !== undefined && [makerToken, takerToken].includes(c.metaToken)), + ), + ); } export function getSnowSwapInfosForPair(takerToken: string, makerToken: string): SnowSwapInfo[] { - return Object.values(MAINNET_SNOWSWAP_INFOS).filter(c => [makerToken, takerToken].every(t => c.tokens.includes(t))); + return Object.values(MAINNET_SNOWSWAP_INFOS).filter(c => + [makerToken, takerToken].every( + t => + (c.tokens.includes(t) && c.metaToken === undefined) || + (c.tokens.includes(t) && c.metaToken !== undefined && [makerToken, takerToken].includes(c.metaToken)), + ), + ); } 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 399db51c02..b5c9bd2abb 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/types.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/types.ts @@ -75,6 +75,7 @@ export interface CurveInfo { buyQuoteFunctionSelector: CurveFunctionSelectors; poolAddress: string; tokens: string[]; + metaToken: string | undefined; } export interface SwerveInfo extends CurveInfo {}