feat: Curve V2 (#262)

* feat: Curve V2

* fix: CurveV2 gas schedule, remove unused import from MixinCurveV2

* feat: FQT address update

* chore: Curve V2 exchange_underlying, adding Polygon atricrypto pool

* prettier

* feat: FQT Polygon address update

* feat: FQT address update
This commit is contained in:
Romain Butteaud 2021-06-10 19:01:11 -07:00 committed by GitHub
parent adf6684c29
commit d07c7d5b69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 241 additions and 63 deletions

View File

@ -27,6 +27,7 @@ import "./mixins/MixinBalancerV2.sol";
import "./mixins/MixinBancor.sol"; import "./mixins/MixinBancor.sol";
import "./mixins/MixinCoFiX.sol"; import "./mixins/MixinCoFiX.sol";
import "./mixins/MixinCurve.sol"; import "./mixins/MixinCurve.sol";
import "./mixins/MixinCurveV2.sol";
import "./mixins/MixinCryptoCom.sol"; import "./mixins/MixinCryptoCom.sol";
import "./mixins/MixinDodo.sol"; import "./mixins/MixinDodo.sol";
import "./mixins/MixinDodoV2.sol"; import "./mixins/MixinDodoV2.sol";
@ -50,6 +51,7 @@ contract BridgeAdapter is
MixinBancor, MixinBancor,
MixinCoFiX, MixinCoFiX,
MixinCurve, MixinCurve,
MixinCurveV2,
MixinCryptoCom, MixinCryptoCom,
MixinDodo, MixinDodo,
MixinDodoV2, MixinDodoV2,
@ -73,6 +75,7 @@ contract BridgeAdapter is
MixinBancor(weth) MixinBancor(weth)
MixinCoFiX() MixinCoFiX()
MixinCurve(weth) MixinCurve(weth)
MixinCurveV2()
MixinCryptoCom() MixinCryptoCom()
MixinDodo() MixinDodo()
MixinDodoV2() MixinDodoV2()
@ -107,6 +110,13 @@ contract BridgeAdapter is
sellAmount, sellAmount,
order.bridgeData order.bridgeData
); );
} else if (protocolId == BridgeProtocols.CURVEV2) {
boughtAmount = _tradeCurveV2(
sellToken,
buyToken,
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.UNISWAPV3) { } else if (protocolId == BridgeProtocols.UNISWAPV3) {
boughtAmount = _tradeUniswapV3( boughtAmount = _tradeUniswapV3(
sellToken, sellToken,

View File

@ -47,4 +47,5 @@ library BridgeProtocols {
uint128 internal constant BALANCERV2 = 17; uint128 internal constant BALANCERV2 = 17;
uint128 internal constant UNISWAPV3 = 18; uint128 internal constant UNISWAPV3 = 18;
uint128 internal constant KYBERDMM = 19; uint128 internal constant KYBERDMM = 19;
uint128 internal constant CURVEV2 = 20;
} }

View File

@ -0,0 +1,71 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2020 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.6.5;
pragma experimental ABIEncoderV2;
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
contract MixinCurveV2 {
using LibERC20TokenV06 for IERC20TokenV06;
using LibSafeMathV06 for uint256;
using LibRichErrorsV06 for bytes;
struct CurveBridgeDataV2 {
address curveAddress;
bytes4 exchangeFunctionSelector;
int128 fromCoinIdx;
int128 toCoinIdx;
}
function _tradeCurveV2(
IERC20TokenV06 sellToken,
IERC20TokenV06 buyToken,
uint256 sellAmount,
bytes memory bridgeData
)
internal
returns (uint256 boughtAmount)
{
// Decode the bridge data to get the Curve metadata.
CurveBridgeDataV2 memory data = abi.decode(bridgeData, (CurveBridgeDataV2));
sellToken.approveIfBelow(data.curveAddress, sellAmount);
uint256 beforeBalance = buyToken.balanceOf(address(this));
(bool success, bytes memory resultData) =
data.curveAddress.call(abi.encodeWithSelector(
data.exchangeFunctionSelector,
data.fromCoinIdx,
data.toCoinIdx,
// dx
sellAmount,
// min dy
1
));
if (!success) {
resultData.rrevert();
}
return buyToken.balanceOf(address(this)).safeSub(beforeBalance);
}
}

View File

@ -43,7 +43,7 @@
"config": { "config": {
"publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,PositiveSlippageFeeTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,AffiliateFeeTransformer,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector,CurveLiquidityProvider,BatchFillNativeOrdersFeature,IBatchFillNativeOrdersFeature,MultiplexFeature,IMultiplexFeature,OtcOrdersFeature,IOtcOrdersFeature", "publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,PositiveSlippageFeeTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,AffiliateFeeTransformer,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector,CurveLiquidityProvider,BatchFillNativeOrdersFeature,IBatchFillNativeOrdersFeature,MultiplexFeature,IMultiplexFeature,OtcOrdersFeature,IOtcOrdersFeature",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.", "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
"abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IFeature|IFlashWallet|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinBalancer|MixinBalancerV2|MixinBancor|MixinCoFiX|MixinCryptoCom|MixinCurve|MixinDodo|MixinDodoV2|MixinKyber|MixinKyberDmm|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestMooniswap|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json" "abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IFeature|IFlashWallet|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinBalancer|MixinBalancerV2|MixinBancor|MixinCoFiX|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinKyber|MixinKyberDmm|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestMooniswap|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -85,6 +85,7 @@ import * as MixinBancor from '../test/generated-artifacts/MixinBancor.json';
import * as MixinCoFiX from '../test/generated-artifacts/MixinCoFiX.json'; import * as MixinCoFiX from '../test/generated-artifacts/MixinCoFiX.json';
import * as MixinCryptoCom from '../test/generated-artifacts/MixinCryptoCom.json'; import * as MixinCryptoCom from '../test/generated-artifacts/MixinCryptoCom.json';
import * as MixinCurve from '../test/generated-artifacts/MixinCurve.json'; import * as MixinCurve from '../test/generated-artifacts/MixinCurve.json';
import * as MixinCurveV2 from '../test/generated-artifacts/MixinCurveV2.json';
import * as MixinDodo from '../test/generated-artifacts/MixinDodo.json'; import * as MixinDodo from '../test/generated-artifacts/MixinDodo.json';
import * as MixinDodoV2 from '../test/generated-artifacts/MixinDodoV2.json'; import * as MixinDodoV2 from '../test/generated-artifacts/MixinDodoV2.json';
import * as MixinKyber from '../test/generated-artifacts/MixinKyber.json'; import * as MixinKyber from '../test/generated-artifacts/MixinKyber.json';
@ -258,6 +259,7 @@ export const artifacts = {
MixinCoFiX: MixinCoFiX as ContractArtifact, MixinCoFiX: MixinCoFiX as ContractArtifact,
MixinCryptoCom: MixinCryptoCom as ContractArtifact, MixinCryptoCom: MixinCryptoCom as ContractArtifact,
MixinCurve: MixinCurve as ContractArtifact, MixinCurve: MixinCurve as ContractArtifact,
MixinCurveV2: MixinCurveV2 as ContractArtifact,
MixinDodo: MixinDodo as ContractArtifact, MixinDodo: MixinDodo as ContractArtifact,
MixinDodoV2: MixinDodoV2 as ContractArtifact, MixinDodoV2: MixinDodoV2 as ContractArtifact,
MixinKyber: MixinKyber as ContractArtifact, MixinKyber: MixinKyber as ContractArtifact,

View File

@ -83,6 +83,7 @@ export * from '../test/generated-wrappers/mixin_bancor';
export * from '../test/generated-wrappers/mixin_co_fi_x'; export * from '../test/generated-wrappers/mixin_co_fi_x';
export * from '../test/generated-wrappers/mixin_crypto_com'; export * from '../test/generated-wrappers/mixin_crypto_com';
export * from '../test/generated-wrappers/mixin_curve'; export * from '../test/generated-wrappers/mixin_curve';
export * from '../test/generated-wrappers/mixin_curve_v2';
export * from '../test/generated-wrappers/mixin_dodo'; export * from '../test/generated-wrappers/mixin_dodo';
export * from '../test/generated-wrappers/mixin_dodo_v2'; export * from '../test/generated-wrappers/mixin_dodo_v2';
export * from '../test/generated-wrappers/mixin_kyber'; export * from '../test/generated-wrappers/mixin_kyber';

View File

@ -116,6 +116,7 @@
"test/generated-artifacts/MixinCoFiX.json", "test/generated-artifacts/MixinCoFiX.json",
"test/generated-artifacts/MixinCryptoCom.json", "test/generated-artifacts/MixinCryptoCom.json",
"test/generated-artifacts/MixinCurve.json", "test/generated-artifacts/MixinCurve.json",
"test/generated-artifacts/MixinCurveV2.json",
"test/generated-artifacts/MixinDodo.json", "test/generated-artifacts/MixinDodo.json",
"test/generated-artifacts/MixinDodoV2.json", "test/generated-artifacts/MixinDodoV2.json",
"test/generated-artifacts/MixinKyber.json", "test/generated-artifacts/MixinKyber.json",

View File

@ -12,6 +12,8 @@ import {
CRYPTO_COM_ROUTER_BY_CHAIN_ID, CRYPTO_COM_ROUTER_BY_CHAIN_ID,
CURVE_MAINNET_INFOS, CURVE_MAINNET_INFOS,
CURVE_POLYGON_INFOS, CURVE_POLYGON_INFOS,
CURVE_V2_MAINNET_INFOS,
CURVE_V2_POLYGON_INFOS,
DFYN_ROUTER_BY_CHAIN_ID, DFYN_ROUTER_BY_CHAIN_ID,
ELLIPSIS_BSC_INFOS, ELLIPSIS_BSC_INFOS,
JULSWAP_ROUTER_BY_CHAIN_ID, JULSWAP_ROUTER_BY_CHAIN_ID,
@ -107,20 +109,44 @@ export function getCurveInfosForPair(chainId: ChainId, takerToken: string, maker
return Object.values(CURVE_MAINNET_INFOS).filter(c => return Object.values(CURVE_MAINNET_INFOS).filter(c =>
[makerToken, takerToken].every( [makerToken, takerToken].every(
t => t =>
(c.tokens.includes(t) && c.metaToken === undefined) || (c.tokens.includes(t) && c.metaTokens === undefined) ||
(c.tokens.includes(t) && (c.tokens.includes(t) &&
c.metaToken !== undefined && [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
[makerToken, takerToken].includes(c.metaToken)),
), ),
); );
case ChainId.Polygon: case ChainId.Polygon:
return Object.values(CURVE_POLYGON_INFOS).filter(c => return Object.values(CURVE_POLYGON_INFOS).filter(c =>
[makerToken, takerToken].every( [makerToken, takerToken].every(
t => t =>
(c.tokens.includes(t) && c.metaToken === undefined) || (c.tokens.includes(t) && c.metaTokens === undefined) ||
(c.tokens.includes(t) && (c.tokens.includes(t) &&
c.metaToken !== undefined && [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
[makerToken, takerToken].includes(c.metaToken)), ),
);
default:
return [];
}
}
// tslint:disable completed-docs
export function getCurveV2InfosForPair(chainId: ChainId, takerToken: string, makerToken: string): CurveInfo[] {
switch (chainId) {
case ChainId.Mainnet:
return Object.values(CURVE_V2_MAINNET_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),
),
);
case ChainId.Polygon:
return Object.values(CURVE_V2_POLYGON_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: default:
@ -135,8 +161,8 @@ export function getSwerveInfosForPair(chainId: ChainId, takerToken: string, make
return Object.values(SWERVE_MAINNET_INFOS).filter(c => return Object.values(SWERVE_MAINNET_INFOS).filter(c =>
[makerToken, takerToken].every( [makerToken, takerToken].every(
t => t =>
(c.tokens.includes(t) && c.metaToken === undefined) || (c.tokens.includes(t) && c.metaTokens === undefined) ||
(c.tokens.includes(t) && c.metaToken !== undefined && [makerToken, takerToken].includes(c.metaToken)), (c.tokens.includes(t) && [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
), ),
); );
} }
@ -148,8 +174,8 @@ export function getSnowSwapInfosForPair(chainId: ChainId, takerToken: string, ma
return Object.values(SNOWSWAP_MAINNET_INFOS).filter(c => return Object.values(SNOWSWAP_MAINNET_INFOS).filter(c =>
[makerToken, takerToken].every( [makerToken, takerToken].every(
t => t =>
(c.tokens.includes(t) && c.metaToken === undefined) || (c.tokens.includes(t) && c.metaTokens === undefined) ||
(c.tokens.includes(t) && c.metaToken !== undefined && [makerToken, takerToken].includes(c.metaToken)), (c.tokens.includes(t) && [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
), ),
); );
} }
@ -161,8 +187,8 @@ export function getNerveInfosForPair(chainId: ChainId, takerToken: string, maker
return Object.values(NERVE_BSC_INFOS).filter(c => return Object.values(NERVE_BSC_INFOS).filter(c =>
[makerToken, takerToken].every( [makerToken, takerToken].every(
t => t =>
(c.tokens.includes(t) && c.metaToken === undefined) || (c.tokens.includes(t) && c.metaTokens === undefined) ||
(c.tokens.includes(t) && c.metaToken !== undefined && [makerToken, takerToken].includes(c.metaToken)), (c.tokens.includes(t) && [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
), ),
); );
} }
@ -174,8 +200,8 @@ export function getBeltInfosForPair(chainId: ChainId, takerToken: string, makerT
return Object.values(BELT_BSC_INFOS).filter(c => return Object.values(BELT_BSC_INFOS).filter(c =>
[makerToken, takerToken].every( [makerToken, takerToken].every(
t => t =>
(c.tokens.includes(t) && c.metaToken === undefined) || (c.tokens.includes(t) && c.metaTokens === undefined) ||
(c.tokens.includes(t) && c.metaToken !== undefined && [makerToken, takerToken].includes(c.metaToken)), (c.tokens.includes(t) && [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
), ),
); );
} }
@ -187,8 +213,8 @@ export function getEllipsisInfosForPair(chainId: ChainId, takerToken: string, ma
return Object.values(ELLIPSIS_BSC_INFOS).filter(c => return Object.values(ELLIPSIS_BSC_INFOS).filter(c =>
[makerToken, takerToken].every( [makerToken, takerToken].every(
t => t =>
(c.tokens.includes(t) && c.metaToken === undefined) || (c.tokens.includes(t) && c.metaTokens === undefined) ||
(c.tokens.includes(t) && c.metaToken !== undefined && [makerToken, takerToken].includes(c.metaToken)), (c.tokens.includes(t) && [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
), ),
); );
} }
@ -198,20 +224,18 @@ export function getSmoothyInfosForPair(chainId: ChainId, takerToken: string, mak
return Object.values(SMOOTHY_BSC_INFOS).filter(c => return Object.values(SMOOTHY_BSC_INFOS).filter(c =>
[makerToken, takerToken].every( [makerToken, takerToken].every(
t => t =>
(c.tokens.includes(t) && c.metaToken === undefined) || (c.tokens.includes(t) && c.metaTokens === undefined) ||
(c.tokens.includes(t) && (c.tokens.includes(t) &&
c.metaToken !== undefined && [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
[makerToken, takerToken].includes(c.metaToken)),
), ),
); );
} else if (chainId === ChainId.Mainnet) { } else if (chainId === ChainId.Mainnet) {
return Object.values(SMOOTHY_MAINNET_INFOS).filter(c => return Object.values(SMOOTHY_MAINNET_INFOS).filter(c =>
[makerToken, takerToken].every( [makerToken, takerToken].every(
t => t =>
(c.tokens.includes(t) && c.metaToken === undefined) || (c.tokens.includes(t) && c.metaTokens === undefined) ||
(c.tokens.includes(t) && (c.tokens.includes(t) &&
c.metaToken !== undefined && [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
[makerToken, takerToken].includes(c.metaToken)),
), ),
); );
} else { } else {
@ -226,8 +250,8 @@ export function getSaddleInfosForPair(chainId: ChainId, takerToken: string, make
return Object.values(SADDLE_MAINNET_INFOS).filter(c => return Object.values(SADDLE_MAINNET_INFOS).filter(c =>
[makerToken, takerToken].every( [makerToken, takerToken].every(
t => t =>
(c.tokens.includes(t) && c.metaToken === undefined) || (c.tokens.includes(t) && c.metaTokens === undefined) ||
(c.tokens.includes(t) && c.metaToken !== undefined && [makerToken, takerToken].includes(c.metaToken)), (c.tokens.includes(t) && [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
), ),
); );
} }
@ -239,8 +263,8 @@ export function getXSigmaInfosForPair(chainId: ChainId, takerToken: string, make
return Object.values(XSIGMA_MAINNET_INFOS).filter(c => return Object.values(XSIGMA_MAINNET_INFOS).filter(c =>
[makerToken, takerToken].every( [makerToken, takerToken].every(
t => t =>
(c.tokens.includes(t) && c.metaToken === undefined) || (c.tokens.includes(t) && c.metaTokens === undefined) ||
(c.tokens.includes(t) && c.metaToken !== undefined && [makerToken, takerToken].includes(c.metaToken)), (c.tokens.includes(t) && [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
), ),
); );
} }
@ -274,6 +298,7 @@ export function getCurveLikeInfosForPair(
makerToken: string, makerToken: string,
source: source:
| ERC20BridgeSource.Curve | ERC20BridgeSource.Curve
| ERC20BridgeSource.CurveV2
| ERC20BridgeSource.Swerve | ERC20BridgeSource.Swerve
| ERC20BridgeSource.SnowSwap | ERC20BridgeSource.SnowSwap
| ERC20BridgeSource.Nerve | ERC20BridgeSource.Nerve
@ -288,6 +313,9 @@ export function getCurveLikeInfosForPair(
case ERC20BridgeSource.Curve: case ERC20BridgeSource.Curve:
pools = getCurveInfosForPair(chainId, takerToken, makerToken); pools = getCurveInfosForPair(chainId, takerToken, makerToken);
break; break;
case ERC20BridgeSource.CurveV2:
pools = getCurveV2InfosForPair(chainId, takerToken, makerToken);
break;
case ERC20BridgeSource.Swerve: case ERC20BridgeSource.Swerve:
pools = getSwerveInfosForPair(chainId, takerToken, makerToken); pools = getSwerveInfosForPair(chainId, takerToken, makerToken);
break; break;

View File

@ -94,6 +94,7 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.Saddle, ERC20BridgeSource.Saddle,
ERC20BridgeSource.XSigma, ERC20BridgeSource.XSigma,
ERC20BridgeSource.UniswapV3, ERC20BridgeSource.UniswapV3,
ERC20BridgeSource.CurveV2,
]), ]),
[ChainId.Ropsten]: new SourceFilters([ [ChainId.Ropsten]: new SourceFilters([
ERC20BridgeSource.Kyber, ERC20BridgeSource.Kyber,
@ -136,6 +137,7 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.Curve, ERC20BridgeSource.Curve,
ERC20BridgeSource.DodoV2, ERC20BridgeSource.DodoV2,
ERC20BridgeSource.Dodo, ERC20BridgeSource.Dodo,
ERC20BridgeSource.CurveV2,
]), ]),
}, },
new SourceFilters([]), new SourceFilters([]),
@ -176,6 +178,7 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.Saddle, ERC20BridgeSource.Saddle,
ERC20BridgeSource.XSigma, ERC20BridgeSource.XSigma,
ERC20BridgeSource.UniswapV3, ERC20BridgeSource.UniswapV3,
ERC20BridgeSource.CurveV2,
]), ]),
[ChainId.Ropsten]: new SourceFilters([ [ChainId.Ropsten]: new SourceFilters([
ERC20BridgeSource.Kyber, ERC20BridgeSource.Kyber,
@ -218,6 +221,7 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.Curve, ERC20BridgeSource.Curve,
ERC20BridgeSource.DodoV2, ERC20BridgeSource.DodoV2,
ERC20BridgeSource.Dodo, ERC20BridgeSource.Dodo,
ERC20BridgeSource.CurveV2,
]), ]),
}, },
new SourceFilters([]), new SourceFilters([]),
@ -399,10 +403,18 @@ export const CURVE_POOLS = {
BUSD: '0x4807862aa8b2bf68830e4c8dc86d0e9a998e085a', BUSD: '0x4807862aa8b2bf68830e4c8dc86d0e9a998e085a',
}; };
export const CURVE_V2_POOLS = {
tricrypto: '0x80466c64868e1ab14a1ddf27a676c3fcbe638fe5',
};
export const CURVE_POLYGON_POOLS = { export const CURVE_POLYGON_POOLS = {
aave: '0x445fe580ef8d70ff569ab36e80c647af338db351', aave: '0x445fe580ef8d70ff569ab36e80c647af338db351',
}; };
export const CURVE_V2_POLYGON_POOLS = {
atricrypto: '0x3fcd5de6a9fc8a99995c406c77dda3ed7e406f81',
};
export const SWERVE_POOLS = { export const SWERVE_POOLS = {
y: '0x329239599afb305da0a2ec69c58f8a6697f9f88d', y: '0x329239599afb305da0a2ec69c58f8a6697f9f88d',
}; };
@ -523,13 +535,15 @@ export const NATIVE_FEE_TOKEN_AMOUNT_BY_CHAIN_ID = valueByChainId(
// Order dependent // Order dependent
const CURVE_TRI_POOL_MAINNET_TOKENS = [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC, MAINNET_TOKENS.USDT]; const CURVE_TRI_POOL_MAINNET_TOKENS = [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC, MAINNET_TOKENS.USDT];
const CURVE_TRI_BTC_POOL_TOKEN = [MAINNET_TOKENS.RenBTC, MAINNET_TOKENS.WBTC, MAINNET_TOKENS.sBTC]; const CURVE_TRI_BTC_POOL_TOKEN = [MAINNET_TOKENS.RenBTC, MAINNET_TOKENS.WBTC, MAINNET_TOKENS.sBTC];
const CURVE_POLYGON_ATRICRYPTO_UNDERLYING_TOKENS = [POLYGON_TOKENS.DAI, POLYGON_TOKENS.USDC, POLYGON_TOKENS.USDT];
const CURVE_POLYGON_ATRICRYPTO_TOKENS = [POLYGON_TOKENS.amDAI, POLYGON_TOKENS.amUSDC, POLYGON_TOKENS.amUSDT];
const createCurveExchangePool = (info: { tokens: string[]; pool: string; gasSchedule: number }) => ({ const createCurveExchangePool = (info: { tokens: string[]; pool: string; gasSchedule: number }) => ({
exchangeFunctionSelector: CurveFunctionSelectors.exchange, exchangeFunctionSelector: CurveFunctionSelectors.exchange,
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy, sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy,
buyQuoteFunctionSelector: CurveFunctionSelectors.None, buyQuoteFunctionSelector: CurveFunctionSelectors.None,
tokens: info.tokens, tokens: info.tokens,
metaToken: undefined, metaTokens: undefined,
poolAddress: info.pool, poolAddress: info.pool,
gasSchedule: info.gasSchedule, gasSchedule: info.gasSchedule,
}); });
@ -539,27 +553,47 @@ const createCurveExchangeUnderlyingPool = (info: { tokens: string[]; pool: strin
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
buyQuoteFunctionSelector: CurveFunctionSelectors.None, buyQuoteFunctionSelector: CurveFunctionSelectors.None,
tokens: info.tokens, tokens: info.tokens,
metaToken: undefined, metaTokens: undefined,
poolAddress: info.pool, poolAddress: info.pool,
gasSchedule: info.gasSchedule, gasSchedule: info.gasSchedule,
}); });
const createCurveMetaTriPool = (info: { token: string; pool: string; gasSchedule: number }) => ({ const createCurveMetaTriPool = (info: { tokens: string[]; pool: string; gasSchedule: number }) => ({
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
buyQuoteFunctionSelector: CurveFunctionSelectors.None, buyQuoteFunctionSelector: CurveFunctionSelectors.None,
tokens: [info.token, ...CURVE_TRI_POOL_MAINNET_TOKENS], tokens: [...info.tokens, ...CURVE_TRI_POOL_MAINNET_TOKENS],
metaToken: info.token, metaTokens: info.tokens,
poolAddress: info.pool, poolAddress: info.pool,
gasSchedule: info.gasSchedule, gasSchedule: info.gasSchedule,
}); });
const createCurveMetaTriBtcPool = (info: { token: string; pool: string; gasSchedule: number }) => ({ const createCurveMetaTriBtcPool = (info: { tokens: string[]; pool: string; gasSchedule: number }) => ({
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying, exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying, sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
buyQuoteFunctionSelector: CurveFunctionSelectors.None, buyQuoteFunctionSelector: CurveFunctionSelectors.None,
tokens: [info.token, ...CURVE_TRI_BTC_POOL_TOKEN], tokens: [...info.tokens, ...CURVE_TRI_BTC_POOL_TOKEN],
metaToken: info.token, metaTokens: info.tokens,
poolAddress: info.pool,
gasSchedule: info.gasSchedule,
});
const createCurveExchangeV2Pool = (info: { tokens: string[]; pool: string; gasSchedule: number }) => ({
exchangeFunctionSelector: CurveFunctionSelectors.exchange_v2,
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_v2,
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
tokens: info.tokens,
metaTokens: undefined,
poolAddress: info.pool,
gasSchedule: info.gasSchedule,
});
const createCurveV2MetaTriPool = (info: { tokens: string[]; pool: string; gasSchedule: number }) => ({
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying_v2,
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying_v2,
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
tokens: [...CURVE_POLYGON_ATRICRYPTO_UNDERLYING_TOKENS, ...info.tokens],
metaTokens: info.tokens,
poolAddress: info.pool, poolAddress: info.pool,
gasSchedule: info.gasSchedule, gasSchedule: info.gasSchedule,
}); });
@ -606,52 +640,52 @@ export const CURVE_MAINNET_INFOS: { [name: string]: CurveInfo } = {
gasSchedule: 176e3, gasSchedule: 176e3,
}), }),
[CURVE_POOLS.GUSD]: createCurveMetaTriPool({ [CURVE_POOLS.GUSD]: createCurveMetaTriPool({
token: MAINNET_TOKENS.GUSD, tokens: [MAINNET_TOKENS.GUSD],
pool: CURVE_POOLS.GUSD, pool: CURVE_POOLS.GUSD,
gasSchedule: 411e3, gasSchedule: 411e3,
}), }),
[CURVE_POOLS.HUSD]: createCurveMetaTriPool({ [CURVE_POOLS.HUSD]: createCurveMetaTriPool({
token: MAINNET_TOKENS.HUSD, tokens: [MAINNET_TOKENS.HUSD],
pool: CURVE_POOLS.HUSD, pool: CURVE_POOLS.HUSD,
gasSchedule: 396e3, gasSchedule: 396e3,
}), }),
[CURVE_POOLS.USDN]: createCurveMetaTriPool({ [CURVE_POOLS.USDN]: createCurveMetaTriPool({
token: MAINNET_TOKENS.USDN, tokens: [MAINNET_TOKENS.USDN],
pool: CURVE_POOLS.USDN, pool: CURVE_POOLS.USDN,
gasSchedule: 398e3, gasSchedule: 398e3,
}), }),
[CURVE_POOLS.mUSD]: createCurveMetaTriPool({ [CURVE_POOLS.mUSD]: createCurveMetaTriPool({
token: MAINNET_TOKENS.mUSD, tokens: [MAINNET_TOKENS.mUSD],
pool: CURVE_POOLS.mUSD, pool: CURVE_POOLS.mUSD,
gasSchedule: 385e3, gasSchedule: 385e3,
}), }),
[CURVE_POOLS.dUSD]: createCurveMetaTriPool({ [CURVE_POOLS.dUSD]: createCurveMetaTriPool({
token: MAINNET_TOKENS.dUSD, tokens: [MAINNET_TOKENS.dUSD],
pool: CURVE_POOLS.dUSD, pool: CURVE_POOLS.dUSD,
gasSchedule: 371e3, gasSchedule: 371e3,
}), }),
[CURVE_POOLS.tBTC]: createCurveMetaTriBtcPool({ [CURVE_POOLS.tBTC]: createCurveMetaTriBtcPool({
token: MAINNET_TOKENS.tBTC, tokens: [MAINNET_TOKENS.tBTC],
pool: CURVE_POOLS.tBTC, pool: CURVE_POOLS.tBTC,
gasSchedule: 482e3, gasSchedule: 482e3,
}), }),
[CURVE_POOLS.pBTC]: createCurveMetaTriBtcPool({ [CURVE_POOLS.pBTC]: createCurveMetaTriBtcPool({
token: MAINNET_TOKENS.pBTC, tokens: [MAINNET_TOKENS.pBTC],
pool: CURVE_POOLS.pBTC, pool: CURVE_POOLS.pBTC,
gasSchedule: 503e3, gasSchedule: 503e3,
}), }),
[CURVE_POOLS.bBTC]: createCurveMetaTriBtcPool({ [CURVE_POOLS.bBTC]: createCurveMetaTriBtcPool({
token: MAINNET_TOKENS.bBTC, tokens: [MAINNET_TOKENS.bBTC],
pool: CURVE_POOLS.bBTC, pool: CURVE_POOLS.bBTC,
gasSchedule: 497e3, gasSchedule: 497e3,
}), }),
[CURVE_POOLS.oBTC]: createCurveMetaTriBtcPool({ [CURVE_POOLS.oBTC]: createCurveMetaTriBtcPool({
token: MAINNET_TOKENS.oBTC, tokens: [MAINNET_TOKENS.oBTC],
pool: CURVE_POOLS.oBTC, pool: CURVE_POOLS.oBTC,
gasSchedule: 488e3, gasSchedule: 488e3,
}), }),
[CURVE_POOLS.UST]: createCurveMetaTriPool({ [CURVE_POOLS.UST]: createCurveMetaTriPool({
token: MAINNET_TOKENS.UST, tokens: [MAINNET_TOKENS.UST],
pool: CURVE_POOLS.UST, pool: CURVE_POOLS.UST,
gasSchedule: 340e3, gasSchedule: 340e3,
}), }),
@ -681,7 +715,7 @@ export const CURVE_MAINNET_INFOS: { [name: string]: CurveInfo } = {
gasSchedule: 580e3, gasSchedule: 580e3,
}), }),
[CURVE_POOLS.USDP]: createCurveMetaTriPool({ [CURVE_POOLS.USDP]: createCurveMetaTriPool({
token: MAINNET_TOKENS.USDP, tokens: [MAINNET_TOKENS.USDP],
pool: CURVE_POOLS.USDP, pool: CURVE_POOLS.USDP,
gasSchedule: 374e3, gasSchedule: 374e3,
}), }),
@ -696,32 +730,32 @@ export const CURVE_MAINNET_INFOS: { [name: string]: CurveInfo } = {
gasSchedule: 319e3, gasSchedule: 319e3,
}), }),
[CURVE_POOLS.TUSD]: createCurveMetaTriPool({ [CURVE_POOLS.TUSD]: createCurveMetaTriPool({
token: MAINNET_TOKENS.TUSD, tokens: [MAINNET_TOKENS.TUSD],
pool: CURVE_POOLS.TUSD, pool: CURVE_POOLS.TUSD,
gasSchedule: 404e3, gasSchedule: 404e3,
}), }),
[CURVE_POOLS.STABLEx]: createCurveMetaTriPool({ [CURVE_POOLS.STABLEx]: createCurveMetaTriPool({
token: MAINNET_TOKENS.STABLEx, tokens: [MAINNET_TOKENS.STABLEx],
pool: CURVE_POOLS.STABLEx, pool: CURVE_POOLS.STABLEx,
gasSchedule: 397e3, gasSchedule: 397e3,
}), }),
[CURVE_POOLS.alUSD]: createCurveMetaTriPool({ [CURVE_POOLS.alUSD]: createCurveMetaTriPool({
token: MAINNET_TOKENS.alUSD, tokens: [MAINNET_TOKENS.alUSD],
pool: CURVE_POOLS.alUSD, pool: CURVE_POOLS.alUSD,
gasSchedule: 387e3, gasSchedule: 387e3,
}), }),
[CURVE_POOLS.FRAX]: createCurveMetaTriPool({ [CURVE_POOLS.FRAX]: createCurveMetaTriPool({
token: MAINNET_TOKENS.FRAX, tokens: [MAINNET_TOKENS.FRAX],
pool: CURVE_POOLS.FRAX, pool: CURVE_POOLS.FRAX,
gasSchedule: 387e3, gasSchedule: 387e3,
}), }),
[CURVE_POOLS.LUSD]: createCurveMetaTriPool({ [CURVE_POOLS.LUSD]: createCurveMetaTriPool({
token: MAINNET_TOKENS.LUSD, tokens: [MAINNET_TOKENS.LUSD],
pool: CURVE_POOLS.LUSD, pool: CURVE_POOLS.LUSD,
gasSchedule: 387e3, gasSchedule: 387e3,
}), }),
[CURVE_POOLS.BUSD]: createCurveMetaTriPool({ [CURVE_POOLS.BUSD]: createCurveMetaTriPool({
token: MAINNET_TOKENS.BUSD, tokens: [MAINNET_TOKENS.BUSD],
pool: CURVE_POOLS.BUSD, pool: CURVE_POOLS.BUSD,
gasSchedule: 387e3, gasSchedule: 387e3,
}), }),
@ -745,19 +779,35 @@ export const CURVE_MAINNET_INFOS: { [name: string]: CurveInfo } = {
}), }),
}; };
export const CURVE_V2_MAINNET_INFOS: { [name: string]: CurveInfo } = {
[CURVE_V2_POOLS.tricrypto]: createCurveExchangeV2Pool({
tokens: [MAINNET_TOKENS.USDT, MAINNET_TOKENS.WBTC, MAINNET_TOKENS.WETH],
pool: CURVE_V2_POOLS.tricrypto,
gasSchedule: 300e3,
}),
};
export const CURVE_POLYGON_INFOS: { [name: string]: CurveInfo } = { export const CURVE_POLYGON_INFOS: { [name: string]: CurveInfo } = {
['aave_exchangeunderlying']: createCurveExchangeUnderlyingPool({ ['aave_exchangeunderlying']: createCurveExchangeUnderlyingPool({
tokens: [POLYGON_TOKENS.DAI, POLYGON_TOKENS.USDC, POLYGON_TOKENS.USDT], tokens: CURVE_POLYGON_ATRICRYPTO_UNDERLYING_TOKENS,
pool: CURVE_POLYGON_POOLS.aave, pool: CURVE_POLYGON_POOLS.aave,
gasSchedule: 300e3, gasSchedule: 300e3,
}), }),
['aave_exchange']: createCurveExchangePool({ ['aave_exchange']: createCurveExchangePool({
tokens: [POLYGON_TOKENS.amDAI, POLYGON_TOKENS.amUSDC, POLYGON_TOKENS.amUSDT], tokens: CURVE_POLYGON_ATRICRYPTO_TOKENS,
pool: CURVE_POLYGON_POOLS.aave, pool: CURVE_POLYGON_POOLS.aave,
gasSchedule: 150e3, gasSchedule: 150e3,
}), }),
}; };
export const CURVE_V2_POLYGON_INFOS: { [name: string]: CurveInfo } = {
[CURVE_V2_POLYGON_POOLS.atricrypto]: createCurveV2MetaTriPool({
tokens: [POLYGON_TOKENS.WBTC, POLYGON_TOKENS.WETH],
pool: CURVE_V2_POLYGON_POOLS.atricrypto,
gasSchedule: 300e3,
}),
};
export const SWERVE_MAINNET_INFOS: { [name: string]: CurveInfo } = { export const SWERVE_MAINNET_INFOS: { [name: string]: CurveInfo } = {
[SWERVE_POOLS.y]: createCurveExchangePool({ [SWERVE_POOLS.y]: createCurveExchangePool({
tokens: [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC, MAINNET_TOKENS.USDT, MAINNET_TOKENS.TUSD], tokens: [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC, MAINNET_TOKENS.USDT, MAINNET_TOKENS.TUSD],
@ -822,7 +872,7 @@ export const SADDLE_MAINNET_INFOS: { [name: string]: CurveInfo } = {
buyQuoteFunctionSelector: CurveFunctionSelectors.None, buyQuoteFunctionSelector: CurveFunctionSelectors.None,
poolAddress: SADDLE_POOLS.stables, poolAddress: SADDLE_POOLS.stables,
tokens: [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC, MAINNET_TOKENS.USDT], tokens: [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC, MAINNET_TOKENS.USDT],
metaToken: undefined, metaTokens: undefined,
gasSchedule: 150e3, gasSchedule: 150e3,
}, },
[SADDLE_POOLS.bitcoins]: { [SADDLE_POOLS.bitcoins]: {
@ -831,7 +881,7 @@ export const SADDLE_MAINNET_INFOS: { [name: string]: CurveInfo } = {
buyQuoteFunctionSelector: CurveFunctionSelectors.None, buyQuoteFunctionSelector: CurveFunctionSelectors.None,
poolAddress: SADDLE_POOLS.bitcoins, poolAddress: SADDLE_POOLS.bitcoins,
tokens: [MAINNET_TOKENS.tBTC, MAINNET_TOKENS.WBTC, MAINNET_TOKENS.RenBTC, MAINNET_TOKENS.sBTC], tokens: [MAINNET_TOKENS.tBTC, MAINNET_TOKENS.WBTC, MAINNET_TOKENS.RenBTC, MAINNET_TOKENS.sBTC],
metaToken: undefined, metaTokens: undefined,
gasSchedule: 150e3, gasSchedule: 150e3,
}, },
}; };
@ -852,7 +902,7 @@ export const SMOOTHY_MAINNET_INFOS: { [name: string]: CurveInfo } = {
MAINNET_TOKENS.PAX, MAINNET_TOKENS.PAX,
MAINNET_TOKENS.GUSD, MAINNET_TOKENS.GUSD,
], ],
metaToken: undefined, metaTokens: undefined,
gasSchedule: 190e3, gasSchedule: 190e3,
}, },
}; };
@ -864,7 +914,7 @@ export const SMOOTHY_BSC_INFOS: { [name: string]: CurveInfo } = {
buyQuoteFunctionSelector: CurveFunctionSelectors.None, buyQuoteFunctionSelector: CurveFunctionSelectors.None,
poolAddress: SMOOTHY_POOLS.syUSD, poolAddress: SMOOTHY_POOLS.syUSD,
tokens: [BSC_TOKENS.BUSD, BSC_TOKENS.USDT, BSC_TOKENS.USDC, BSC_TOKENS.DAI, BSC_TOKENS.PAX, BSC_TOKENS.UST], tokens: [BSC_TOKENS.BUSD, BSC_TOKENS.USDT, BSC_TOKENS.USDC, BSC_TOKENS.DAI, BSC_TOKENS.PAX, BSC_TOKENS.UST],
metaToken: undefined, metaTokens: undefined,
gasSchedule: 90e3, gasSchedule: 90e3,
}, },
}; };
@ -876,7 +926,7 @@ export const NERVE_BSC_INFOS: { [name: string]: CurveInfo } = {
buyQuoteFunctionSelector: CurveFunctionSelectors.None, buyQuoteFunctionSelector: CurveFunctionSelectors.None,
poolAddress: NERVE_POOLS.threePool, poolAddress: NERVE_POOLS.threePool,
tokens: [BSC_TOKENS.BUSD, BSC_TOKENS.USDT, BSC_TOKENS.USDC], tokens: [BSC_TOKENS.BUSD, BSC_TOKENS.USDT, BSC_TOKENS.USDC],
metaToken: undefined, metaTokens: undefined,
gasSchedule: 140e3, gasSchedule: 140e3,
}, },
}; };
@ -1300,6 +1350,7 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
[ERC20BridgeSource.Eth2Dai]: () => 400e3, [ERC20BridgeSource.Eth2Dai]: () => 400e3,
[ERC20BridgeSource.Kyber]: () => 450e3, [ERC20BridgeSource.Kyber]: () => 450e3,
[ERC20BridgeSource.Curve]: fillData => (fillData as CurveFillData).pool.gasSchedule, [ERC20BridgeSource.Curve]: fillData => (fillData as CurveFillData).pool.gasSchedule,
[ERC20BridgeSource.CurveV2]: fillData => (fillData as CurveFillData).pool.gasSchedule,
[ERC20BridgeSource.Swerve]: fillData => (fillData as CurveFillData).pool.gasSchedule, [ERC20BridgeSource.Swerve]: fillData => (fillData as CurveFillData).pool.gasSchedule,
[ERC20BridgeSource.SnowSwap]: fillData => (fillData as CurveFillData).pool.gasSchedule, [ERC20BridgeSource.SnowSwap]: fillData => (fillData as CurveFillData).pool.gasSchedule,
[ERC20BridgeSource.Nerve]: fillData => (fillData as CurveFillData).pool.gasSchedule, [ERC20BridgeSource.Nerve]: fillData => (fillData as CurveFillData).pool.gasSchedule,

View File

@ -161,6 +161,8 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'ComethSwap'); return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'ComethSwap');
case ERC20BridgeSource.Dfyn: case ERC20BridgeSource.Dfyn:
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'Dfyn'); return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'Dfyn');
case ERC20BridgeSource.CurveV2:
return encodeBridgeSourceId(BridgeProtocol.CurveV2, 'CurveV2');
default: default:
throw new Error(AggregationError.NoBridgeForSource); throw new Error(AggregationError.NoBridgeForSource);
} }
@ -183,6 +185,7 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
switch (order.source) { switch (order.source) {
case ERC20BridgeSource.Curve: case ERC20BridgeSource.Curve:
case ERC20BridgeSource.CurveV2:
case ERC20BridgeSource.Swerve: case ERC20BridgeSource.Swerve:
case ERC20BridgeSource.SnowSwap: case ERC20BridgeSource.SnowSwap:
case ERC20BridgeSource.Nerve: case ERC20BridgeSource.Nerve:
@ -392,6 +395,7 @@ export const BRIDGE_ENCODERS: {
]), ]),
// Curve like // Curve like
[ERC20BridgeSource.Curve]: curveEncoder, [ERC20BridgeSource.Curve]: curveEncoder,
[ERC20BridgeSource.CurveV2]: curveEncoder,
[ERC20BridgeSource.Swerve]: curveEncoder, [ERC20BridgeSource.Swerve]: curveEncoder,
[ERC20BridgeSource.SnowSwap]: curveEncoder, [ERC20BridgeSource.SnowSwap]: curveEncoder,
[ERC20BridgeSource.Nerve]: curveEncoder, [ERC20BridgeSource.Nerve]: curveEncoder,

View File

@ -1213,6 +1213,7 @@ export class SamplerOperations {
), ),
); );
case ERC20BridgeSource.Curve: case ERC20BridgeSource.Curve:
case ERC20BridgeSource.CurveV2:
case ERC20BridgeSource.Swerve: case ERC20BridgeSource.Swerve:
case ERC20BridgeSource.SnowSwap: case ERC20BridgeSource.SnowSwap:
case ERC20BridgeSource.Nerve: case ERC20BridgeSource.Nerve:
@ -1466,6 +1467,7 @@ export class SamplerOperations {
), ),
); );
case ERC20BridgeSource.Curve: case ERC20BridgeSource.Curve:
case ERC20BridgeSource.CurveV2:
case ERC20BridgeSource.Swerve: case ERC20BridgeSource.Swerve:
case ERC20BridgeSource.SnowSwap: case ERC20BridgeSource.SnowSwap:
case ERC20BridgeSource.Nerve: case ERC20BridgeSource.Nerve:

View File

@ -66,6 +66,7 @@ export enum ERC20BridgeSource {
Saddle = 'Saddle', Saddle = 'Saddle',
XSigma = 'xSigma', XSigma = 'xSigma',
UniswapV3 = 'Uniswap_V3', UniswapV3 = 'Uniswap_V3',
CurveV2 = 'Curve_V2',
// BSC only // BSC only
PancakeSwap = 'PancakeSwap', PancakeSwap = 'PancakeSwap',
PancakeSwapV2 = 'PancakeSwap_V2', PancakeSwapV2 = 'PancakeSwap_V2',
@ -96,6 +97,11 @@ export enum CurveFunctionSelectors {
get_dx_underlying = '0x0e71d1b9', get_dx_underlying = '0x0e71d1b9',
get_dy = '0x5e0d443f', get_dy = '0x5e0d443f',
get_dx = '0x67df02ca', get_dx = '0x67df02ca',
// Curve V2
exchange_v2 = '0x5b41b908',
exchange_underlying_v2 = '0x65b2489b',
get_dy_v2 = '0x556d6e9f',
get_dy_underlying_v2 = '0x85f11d1e',
// Smoothy // Smoothy
swap_uint256 = '0x5673b02d', // swap(uint256,uint256,uint256,uint256) swap_uint256 = '0x5673b02d', // swap(uint256,uint256,uint256,uint256)
get_swap_amount = '0x45cf2ef6', // getSwapAmount(uint256,uint256,uint256) get_swap_amount = '0x45cf2ef6', // getSwapAmount(uint256,uint256,uint256)
@ -114,7 +120,7 @@ export interface CurveInfo {
buyQuoteFunctionSelector: CurveFunctionSelectors; buyQuoteFunctionSelector: CurveFunctionSelectors;
poolAddress: string; poolAddress: string;
tokens: string[]; tokens: string[];
metaToken: string | undefined; metaTokens: string[] | undefined;
gasSchedule: number; gasSchedule: number;
} }

View File

@ -36,7 +36,7 @@
"wethTransformer": "0xb2bc06a4efb20fc6553a69dbfa49b7be938034a7", "wethTransformer": "0xb2bc06a4efb20fc6553a69dbfa49b7be938034a7",
"payTakerTransformer": "0x4638a7ebe75b911b995d0ec73a81e4f85f41f24e", "payTakerTransformer": "0x4638a7ebe75b911b995d0ec73a81e4f85f41f24e",
"affiliateFeeTransformer": "0xda6d9fc5998f550a094585cf9171f0e8ee3ac59f", "affiliateFeeTransformer": "0xda6d9fc5998f550a094585cf9171f0e8ee3ac59f",
"fillQuoteTransformer": "0xd12a34076a4d9eac4cb82d87411d958641d0db9b", "fillQuoteTransformer": "0x75665d9a15a5212db8668bc3eb46fe09df8335af",
"positiveSlippageFeeTransformer": "0xa9416ce1dbde8d331210c07b5c253d94ee4cc3fd" "positiveSlippageFeeTransformer": "0xa9416ce1dbde8d331210c07b5c253d94ee4cc3fd"
} }
}, },
@ -77,7 +77,7 @@
"wethTransformer": "0x05ad19aa3826e0609a19568ffbd1dfe86c6c7184", "wethTransformer": "0x05ad19aa3826e0609a19568ffbd1dfe86c6c7184",
"payTakerTransformer": "0x6d0ebf2bcd9cc93ec553b60ad201943dcca4e291", "payTakerTransformer": "0x6d0ebf2bcd9cc93ec553b60ad201943dcca4e291",
"affiliateFeeTransformer": "0x6588256778ca4432fa43983ac685c45efb2379e2", "affiliateFeeTransformer": "0x6588256778ca4432fa43983ac685c45efb2379e2",
"fillQuoteTransformer": "0xfdabf2a405034fd9034ddc51ba1189cbed6bd651", "fillQuoteTransformer": "0xc7d935c79e4f01ed29e92950a158807b31f7b799",
"positiveSlippageFeeTransformer": "0x8b332f700fd37e71c5c5b26c4d78b5ca63dd33b2" "positiveSlippageFeeTransformer": "0x8b332f700fd37e71c5c5b26c4d78b5ca63dd33b2"
} }
}, },
@ -282,7 +282,7 @@
"wethTransformer": "0xe309d011cc6f189a3e8dcba85922715a019fed38", "wethTransformer": "0xe309d011cc6f189a3e8dcba85922715a019fed38",
"payTakerTransformer": "0x5ba7b9be86cda01cfbf56e0fb97184783be9dda1", "payTakerTransformer": "0x5ba7b9be86cda01cfbf56e0fb97184783be9dda1",
"affiliateFeeTransformer": "0xbed27284b42e5684e987169cf1da09c5d6c49fa8", "affiliateFeeTransformer": "0xbed27284b42e5684e987169cf1da09c5d6c49fa8",
"fillQuoteTransformer": "0x2a0b60642d58ca819a6f3a3b4a6066be0df0486c", "fillQuoteTransformer": "0xf708d512b8a82e2862543a630403327174410baf",
"positiveSlippageFeeTransformer": "0x4cd8f1c0df4d40fcc1e073845d5f6f4ed5cc8dab" "positiveSlippageFeeTransformer": "0x4cd8f1c0df4d40fcc1e073845d5f6f4ed5cc8dab"
} }
}, },

View File

@ -129,6 +129,7 @@ export enum BridgeProtocol {
BalancerV2, BalancerV2,
UniswapV3, UniswapV3,
KyberDmm, KyberDmm,
CurveV2,
} }
// tslint:enable: enum-naming // tslint:enable: enum-naming