From 411548a33eacb0b19f0baf38371425789ad51485 Mon Sep 17 00:00:00 2001 From: Kim Persson Date: Tue, 27 Apr 2021 00:51:04 +0200 Subject: [PATCH] feat: PancakeSwap 2 integration [TKR-83] (#211) * feat: PancakeSwap 2 integration * chore: add PancakeSwap V2 changelog entry Co-authored-by: Romain Butteaud --- packages/asset-swapper/CHANGELOG.json | 9 +++++++++ .../bridge_source_utils.ts | 6 +++++- .../utils/market_operation_utils/constants.ts | 18 ++++++++++++++++++ .../src/utils/market_operation_utils/orders.ts | 4 ++++ .../sampler_operations.ts | 2 ++ .../src/utils/market_operation_utils/types.ts | 1 + .../test/market_operation_utils_test.ts | 1 + 7 files changed, 40 insertions(+), 1 deletion(-) diff --git a/packages/asset-swapper/CHANGELOG.json b/packages/asset-swapper/CHANGELOG.json index c13387b1af..dbd0d17cfb 100644 --- a/packages/asset-swapper/CHANGELOG.json +++ b/packages/asset-swapper/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "6.7.0", + "changes": [ + { + "note": "Support PancakeSwap V2", + "pr": 211 + } + ] + }, { "version": "6.6.1", "changes": [ 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 f6cd266009..4b1823e432 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 @@ -15,6 +15,7 @@ import { NERVE_BSC_INFOS, NULL_ADDRESS, PANCAKESWAP_ROUTER_BY_CHAIN_ID, + PANCAKESWAP_V2_ROUTER_BY_CHAIN_ID, SADDLE_MAINNET_INFOS, SHELL_POOLS_BY_CHAIN_ID, SMOOTHY_BSC_INFOS, @@ -253,7 +254,8 @@ export function uniswapV2LikeRouterAddress( | ERC20BridgeSource.CryptoCom | ERC20BridgeSource.PancakeSwap | ERC20BridgeSource.BakerySwap - | ERC20BridgeSource.KyberDmm, + | ERC20BridgeSource.KyberDmm + | ERC20BridgeSource.PancakeSwapV2, ): string { switch (source) { case ERC20BridgeSource.UniswapV2: @@ -268,6 +270,8 @@ export function uniswapV2LikeRouterAddress( return BAKERYSWAP_ROUTER_BY_CHAIN_ID[chainId]; case ERC20BridgeSource.KyberDmm: return KYBER_DMM_ROUTER_BY_CHAIN_ID[chainId]; + case ERC20BridgeSource.PancakeSwapV2: + return PANCAKESWAP_V2_ROUTER_BY_CHAIN_ID[chainId]; default: throw new Error(`Unknown UniswapV2 like source ${source}`); } 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 a10fb38d65..2e5e8da4ef 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/constants.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/constants.ts @@ -109,6 +109,7 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId( ERC20BridgeSource.PancakeSwap, ERC20BridgeSource.SushiSwap, ERC20BridgeSource.Smoothy, + ERC20BridgeSource.PancakeSwapV2, ]), }, @@ -170,6 +171,7 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId( ERC20BridgeSource.PancakeSwap, ERC20BridgeSource.SushiSwap, ERC20BridgeSource.Smoothy, + ERC20BridgeSource.PancakeSwapV2, ]), }, new SourceFilters([]), @@ -990,6 +992,13 @@ export const PANCAKESWAP_ROUTER_BY_CHAIN_ID = valueByChainId( NULL_ADDRESS, ); +export const PANCAKESWAP_V2_ROUTER_BY_CHAIN_ID = valueByChainId( + { + [ChainId.BSC]: '0x10ed43c718714eb63d5aa57b78b54704e256024e', + }, + NULL_ADDRESS, +); + export const BAKERYSWAP_ROUTER_BY_CHAIN_ID = valueByChainId( { [ChainId.BSC]: '0xcde540d7eafe93ac5fe6233bee57e1270d3e330f', @@ -1136,6 +1145,15 @@ export const DEFAULT_GAS_SCHEDULE: Required = { } return gas; }, + [ERC20BridgeSource.PancakeSwapV2]: (fillData?: FillData) => { + // TODO: Different base cost if to/from ETH. + let gas = 90e3; + const path = (fillData as UniswapV2FillData).tokenAddressPath; + if (path.length > 2) { + gas += (path.length - 2) * 60e3; // +60k for each hop. + } + return gas; + }, }; export const DEFAULT_FEE_SCHEDULE: Required = { ...DEFAULT_GAS_SCHEDULE }; 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 662a13f443..7c54b3f024 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/orders.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/orders.ts @@ -134,6 +134,8 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s return encodeBridgeSourceId(BridgeProtocol.Curve, 'Smoothy'); case ERC20BridgeSource.Saddle: return encodeBridgeSourceId(BridgeProtocol.Nerve, 'Saddle'); + case ERC20BridgeSource.PancakeSwapV2: + return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'PancakeSwapV2'); default: throw new Error(AggregationError.NoBridgeForSource); } @@ -187,6 +189,7 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder case ERC20BridgeSource.PancakeSwap: case ERC20BridgeSource.BakerySwap: case ERC20BridgeSource.KyberDmm: + case ERC20BridgeSource.PancakeSwapV2: const uniswapV2FillData = (order as OptimizedMarketBridgeOrder).fillData; bridgeData = encoder.encode([uniswapV2FillData.router, uniswapV2FillData.tokenAddressPath]); break; @@ -334,6 +337,7 @@ export const BRIDGE_ENCODERS: { // BSC [ERC20BridgeSource.PancakeSwap]: routerAddressPathEncoder, [ERC20BridgeSource.BakerySwap]: routerAddressPathEncoder, + [ERC20BridgeSource.PancakeSwapV2]: routerAddressPathEncoder, }; function getFillTokenAmounts(fill: CollapsedFill, side: MarketOperation): [BigNumber, BigNumber] { 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 9e47d32852..0501f50aa4 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 @@ -1088,6 +1088,7 @@ export class SamplerOperations { case ERC20BridgeSource.PancakeSwap: case ERC20BridgeSource.BakerySwap: case ERC20BridgeSource.KyberDmm: + case ERC20BridgeSource.PancakeSwapV2: const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source); if (!isValidAddress(uniLikeRouter)) { return []; @@ -1297,6 +1298,7 @@ export class SamplerOperations { case ERC20BridgeSource.PancakeSwap: case ERC20BridgeSource.BakerySwap: case ERC20BridgeSource.KyberDmm: + case ERC20BridgeSource.PancakeSwapV2: const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source); if (!isValidAddress(uniLikeRouter)) { return []; 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 7e8d6aaf47..1aa1ad1058 100644 --- a/packages/asset-swapper/src/utils/market_operation_utils/types.ts +++ b/packages/asset-swapper/src/utils/market_operation_utils/types.ts @@ -69,6 +69,7 @@ export enum ERC20BridgeSource { Nerve = 'Nerve', Belt = 'Belt', Ellipsis = 'Ellipsis', + PancakeSwapV2 = 'PancakeSwap_V2', } // tslint:disable: enum-naming diff --git a/packages/asset-swapper/test/market_operation_utils_test.ts b/packages/asset-swapper/test/market_operation_utils_test.ts index 3f788f076a..2803d848df 100644 --- a/packages/asset-swapper/test/market_operation_utils_test.ts +++ b/packages/asset-swapper/test/market_operation_utils_test.ts @@ -72,6 +72,7 @@ const DEFAULT_EXCLUDED = [ ERC20BridgeSource.Smoothy, ERC20BridgeSource.Component, ERC20BridgeSource.Saddle, + ERC20BridgeSource.PancakeSwapV2, ]; const BUY_SOURCES = BUY_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Mainnet].sources; const SELL_SOURCES = SELL_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Mainnet].sources;