From 8589ba728c67ca600dd5056ca5af5c2be939af7a Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Thu, 4 Nov 2021 16:34:48 +1000 Subject: [PATCH] feat: [Avalanche] Add Curve, CurveV2 and KyberDMM (#363) * feat: [Avalanche] Add Curve, CurveV2 and KyberDMM * CHANGELOG * fix missing file * lint --- packages/asset-swapper/CHANGELOG.json | 10 ++++ .../contracts/src/KyberDmmSampler.sol | 5 +- .../bridge_source_utils.ts | 20 +++++++ .../utils/market_operation_utils/constants.ts | 58 ++++++++++++++++++- 4 files changed, 91 insertions(+), 2 deletions(-) diff --git a/packages/asset-swapper/CHANGELOG.json b/packages/asset-swapper/CHANGELOG.json index bd2bd7a01b..f55c3417b0 100644 --- a/packages/asset-swapper/CHANGELOG.json +++ b/packages/asset-swapper/CHANGELOG.json @@ -1,4 +1,14 @@ [ + { + "timestamp": 1635903615, + "version": "16.31.0", + "changes": [ + { + "note": "Added `Curve`, `Curve_V2` and `KyberDmm` to Avalanche", + "pr": 363 + } + ] + }, { "timestamp": 1635903615, "version": "16.30.1", diff --git a/packages/asset-swapper/contracts/src/KyberDmmSampler.sol b/packages/asset-swapper/contracts/src/KyberDmmSampler.sol index 4e205ec7c0..29ea8c01b3 100644 --- a/packages/asset-swapper/contracts/src/KyberDmmSampler.sol +++ b/packages/asset-swapper/contracts/src/KyberDmmSampler.sol @@ -159,8 +159,11 @@ contract KyberDmmSampler (path[i], path[i + 1]) returns (address[] memory allPools) { + if (allPools.length == 0) { + return new address[](0); + } + uint256 maxSupply = 0; - require(allPools.length >= 1, "KyberDMMSampler/NO_POOLS_FOUND"); for (uint256 j = 0; j < allPools.length; j++) { uint256 totalSupply = IKyberDmmPool(allPools[j]).totalSupply(); if (totalSupply > maxSupply) { diff --git a/packages/asset-swapper/src/utils/market_operation_utils/bridge_source_utils.ts b/packages/asset-swapper/src/utils/market_operation_utils/bridge_source_utils.ts index 082f6d726c..9f64846b38 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/bridge_source_utils.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/bridge_source_utils.ts @@ -11,9 +11,11 @@ import { COMETHSWAP_ROUTER_BY_CHAIN_ID, COMPONENT_POOLS_BY_CHAIN_ID, CRYPTO_COM_ROUTER_BY_CHAIN_ID, + CURVE_AVALANCHE_INFOS, CURVE_FANTOM_INFOS, CURVE_MAINNET_INFOS, CURVE_POLYGON_INFOS, + CURVE_V2_AVALANCHE_INFOS, CURVE_V2_FANTOM_INFOS, CURVE_V2_MAINNET_INFOS, CURVE_V2_POLYGON_INFOS, @@ -146,6 +148,15 @@ export function getCurveInfosForPair(chainId: ChainId, takerToken: string, maker [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0), ), ); + case ChainId.Avalanche: + return Object.values(CURVE_AVALANCHE_INFOS).filter(c => + [makerToken, takerToken].every( + t => + (c.tokens.includes(t) && c.metaTokens === undefined) || + (c.tokens.includes(t) && + [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0), + ), + ); default: return []; } @@ -181,6 +192,15 @@ export function getCurveV2InfosForPair(chainId: ChainId, takerToken: string, mak [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0), ), ); + case ChainId.Avalanche: + return Object.values(CURVE_V2_AVALANCHE_INFOS).filter(c => + [makerToken, takerToken].every( + t => + (c.tokens.includes(t) && c.metaTokens === undefined) || + (c.tokens.includes(t) && + [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0), + ), + ); default: return []; } 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 ea7226a1c8..d41d9934d8 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/constants.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/constants.ts @@ -136,6 +136,7 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId( ERC20BridgeSource.FirebirdOneSwap, ERC20BridgeSource.JetSwap, ERC20BridgeSource.ACryptos, + ERC20BridgeSource.KyberDmm, ]), [ChainId.Polygon]: new SourceFilters([ ERC20BridgeSource.SushiSwap, @@ -163,6 +164,9 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId( ERC20BridgeSource.Pangolin, ERC20BridgeSource.TraderJoe, ERC20BridgeSource.SushiSwap, + ERC20BridgeSource.Curve, + ERC20BridgeSource.CurveV2, + ERC20BridgeSource.KyberDmm, ]), [ChainId.Fantom]: new SourceFilters([ ERC20BridgeSource.MultiHop, @@ -250,6 +254,7 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId( ERC20BridgeSource.FirebirdOneSwap, ERC20BridgeSource.JetSwap, ERC20BridgeSource.ACryptos, + ERC20BridgeSource.KyberDmm, ]), [ChainId.Polygon]: new SourceFilters([ ERC20BridgeSource.SushiSwap, @@ -277,6 +282,9 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId( ERC20BridgeSource.Pangolin, ERC20BridgeSource.TraderJoe, ERC20BridgeSource.SushiSwap, + ERC20BridgeSource.Curve, + ERC20BridgeSource.CurveV2, + ERC20BridgeSource.KyberDmm, ]), [ChainId.Fantom]: new SourceFilters([ ERC20BridgeSource.MultiHop, @@ -449,8 +457,13 @@ export const POLYGON_TOKENS = { export const AVALANCHE_TOKENS = { WAVAX: '0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7', WETH: '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab', - USDT: '0xc7198437980c041c805a1edcba50c1ce5db95118', + WBTC: '0x50b7545627a5162f82a992c33b87adc75187b218', DAI: '0xd586e7f844cea2f87f50152665bcbc2c279d8d70', + USDC: '0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664', + USDT: '0xc7198437980c041c805a1edcba50c1ce5db95118', + aDAI: '0x47afa96cdc9fab46904a55a6ad4bf6660b53c38a', + aUSDC: '0x46a51127c3ce23fb7ab1de06226147f446e4a857', + aUSDT: '0x532e6537fea298397212f09a61e03311686f548e', }; export const FANTOM_TOKENS = { @@ -524,6 +537,14 @@ export const CURVE_V2_POLYGON_POOLS = { atricrypto3: '0x1d8b86e3d88cdb2d34688e87e72f388cb541b7c8', }; +export const CURVE_AVALANCHE_POOLS = { + aave: '0x7f90122bf0700f9e7e1f688fe926940e8839f353', +}; + +export const CURVE_V2_AVALANCHE_POOLS = { + atricrypto: '0x58e57ca18b7a47112b877e31929798cd3d703b0f', +}; + export const CURVE_FANTOM_POOLS = { fUSDT: '0x92d5ebf3593a92888c25c0abef126583d4b5312e', twoPool: '0x27e611fd27b276acbd5ffd632e5eaebec9761e40', @@ -631,6 +652,7 @@ export const DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID = valueByChainId( AVALANCHE_TOKENS.WETH, AVALANCHE_TOKENS.DAI, AVALANCHE_TOKENS.USDT, + AVALANCHE_TOKENS.USDC, ], [ChainId.Fantom]: [FANTOM_TOKENS.WFTM, FANTOM_TOKENS.WETH, FANTOM_TOKENS.DAI, FANTOM_TOKENS.USDC], }, @@ -999,6 +1021,37 @@ export const CURVE_V2_POLYGON_INFOS: { [name: string]: CurveInfo } = { }), }; +export const CURVE_AVALANCHE_INFOS: { [name: string]: CurveInfo } = { + ['aave_exchangeunderlying']: createCurveExchangeUnderlyingPool({ + tokens: [AVALANCHE_TOKENS.DAI, AVALANCHE_TOKENS.USDC, AVALANCHE_TOKENS.USDT], + pool: CURVE_AVALANCHE_POOLS.aave, + gasSchedule: 850e3, + }), + ['aave_exchange']: createCurveExchangePool({ + tokens: [AVALANCHE_TOKENS.aDAI, AVALANCHE_TOKENS.aUSDC, AVALANCHE_TOKENS.aUSDT], + pool: CURVE_AVALANCHE_POOLS.aave, + gasSchedule: 150e3, + }), +}; + +export const CURVE_V2_AVALANCHE_INFOS: { [name: string]: CurveInfo } = { + [CURVE_V2_AVALANCHE_POOLS.atricrypto]: { + exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying_v2, + sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying_v2, + buyQuoteFunctionSelector: CurveFunctionSelectors.None, + tokens: [ + AVALANCHE_TOKENS.DAI, + AVALANCHE_TOKENS.USDC, + AVALANCHE_TOKENS.USDT, + AVALANCHE_TOKENS.WBTC, + AVALANCHE_TOKENS.WETH, + ], + metaTokens: undefined, + poolAddress: CURVE_V2_AVALANCHE_POOLS.atricrypto, + gasSchedule: 1300e3, + }, +}; + // TODO: modify gasSchedule export const CURVE_FANTOM_INFOS: { [name: string]: CurveInfo } = { [CURVE_FANTOM_POOLS.ren]: createCurveExchangePool({ @@ -1389,6 +1442,9 @@ export const KYBER_DMM_ROUTER_BY_CHAIN_ID = valueByChainId( { [ChainId.Mainnet]: '0x1c87257f5e8609940bc751a07bb085bb7f8cdbe6', [ChainId.Polygon]: '0x546c79662e028b661dfb4767664d0273184e4dd1', + [ChainId.BSC]: '0x78df70615ffc8066cc0887917f2cd72092c86409', + [ChainId.Avalanche]: '0x8efa5a9ad6d594cf76830267077b78ce0bc5a5f8', + [ChainId.Fantom]: '0x5d5a5a0a465129848c2549669e12cdc2f8de039a', }, NULL_ADDRESS, );