feat: Add Velodrome support [TKR-432] (#494)
* Implement MixinVelodrome * Add preliminary implementation of VelodromeSampler * Add Velodrome in BridgeProtocol of transformer_utils.ts * Fix MixinVelodrome * Wire Velodrome sampler in market_operation_utils * Fix lint error * Remove gas schedule TODO * Format VelodromeSampler.sol * Fix MixinVelodrome * Update CHANGELOG.json
This commit is contained in:
parent
2c6a714b71
commit
1cc59ab1ab
@ -1,4 +1,13 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "0.35.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Adds support for Velodrome OptimismBridgeAdapter",
|
||||||
|
"pr": 494
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "0.34.0",
|
"version": "0.34.0",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
@ -56,4 +56,5 @@ library BridgeProtocols {
|
|||||||
uint128 internal constant GMX = 26;
|
uint128 internal constant GMX = 26;
|
||||||
uint128 internal constant PLATYPUS = 27;
|
uint128 internal constant PLATYPUS = 27;
|
||||||
uint128 internal constant BANCORV3 = 28;
|
uint128 internal constant BANCORV3 = 28;
|
||||||
|
uint128 internal constant VELODROME = 29;
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import "./mixins/MixinCurve.sol";
|
|||||||
import "./mixins/MixinCurveV2.sol";
|
import "./mixins/MixinCurveV2.sol";
|
||||||
import "./mixins/MixinNerve.sol";
|
import "./mixins/MixinNerve.sol";
|
||||||
import "./mixins/MixinUniswapV3.sol";
|
import "./mixins/MixinUniswapV3.sol";
|
||||||
|
import "./mixins/MixinVelodrome.sol";
|
||||||
import "./mixins/MixinZeroExBridge.sol";
|
import "./mixins/MixinZeroExBridge.sol";
|
||||||
|
|
||||||
contract OptimismBridgeAdapter is
|
contract OptimismBridgeAdapter is
|
||||||
@ -34,6 +35,7 @@ contract OptimismBridgeAdapter is
|
|||||||
MixinCurveV2,
|
MixinCurveV2,
|
||||||
MixinNerve,
|
MixinNerve,
|
||||||
MixinUniswapV3,
|
MixinUniswapV3,
|
||||||
|
MixinVelodrome,
|
||||||
MixinZeroExBridge
|
MixinZeroExBridge
|
||||||
{
|
{
|
||||||
constructor(IEtherTokenV06 weth)
|
constructor(IEtherTokenV06 weth)
|
||||||
@ -83,6 +85,14 @@ contract OptimismBridgeAdapter is
|
|||||||
sellAmount,
|
sellAmount,
|
||||||
order.bridgeData
|
order.bridgeData
|
||||||
);
|
);
|
||||||
|
} else if (protocolId == BridgeProtocols.VELODROME) {
|
||||||
|
if (dryRun) { return (0, true); }
|
||||||
|
boughtAmount = _tradeVelodrome(
|
||||||
|
sellToken,
|
||||||
|
buyToken,
|
||||||
|
sellAmount,
|
||||||
|
order.bridgeData
|
||||||
|
);
|
||||||
} else if (protocolId == BridgeProtocols.UNKNOWN) {
|
} else if (protocolId == BridgeProtocols.UNKNOWN) {
|
||||||
if (dryRun) { return (0, true); }
|
if (dryRun) { return (0, true); }
|
||||||
boughtAmount = _tradeZeroExBridge(
|
boughtAmount = _tradeZeroExBridge(
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2022 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-erc20/contracts/src/v06/LibERC20TokenV06.sol";
|
||||||
|
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||||
|
|
||||||
|
interface IVelodromeRouter {
|
||||||
|
function swapExactTokensForTokensSimple(
|
||||||
|
uint256 amountIn,
|
||||||
|
uint256 amountOutMin,
|
||||||
|
address tokenFrom,
|
||||||
|
address tokenTo,
|
||||||
|
bool stable,
|
||||||
|
address to,
|
||||||
|
uint256 deadline
|
||||||
|
) external returns (uint256[] memory amounts);
|
||||||
|
}
|
||||||
|
|
||||||
|
contract MixinVelodrome {
|
||||||
|
using LibERC20TokenV06 for IERC20TokenV06;
|
||||||
|
|
||||||
|
function _tradeVelodrome(
|
||||||
|
IERC20TokenV06 sellToken,
|
||||||
|
IERC20TokenV06 buyToken,
|
||||||
|
uint256 sellAmount,
|
||||||
|
bytes memory bridgeData
|
||||||
|
)
|
||||||
|
internal
|
||||||
|
returns (uint256 boughtAmount)
|
||||||
|
{
|
||||||
|
|
||||||
|
(IVelodromeRouter router, bool stable) = abi.decode(bridgeData, (IVelodromeRouter, bool));
|
||||||
|
sellToken.approveIfBelow(address(router), sellAmount);
|
||||||
|
|
||||||
|
boughtAmount = router.swapExactTokensForTokensSimple(
|
||||||
|
sellAmount,
|
||||||
|
0,
|
||||||
|
address(sellToken),
|
||||||
|
address(buyToken),
|
||||||
|
stable,
|
||||||
|
address(this),
|
||||||
|
block.timestamp + 1
|
||||||
|
)[1];
|
||||||
|
}
|
||||||
|
}
|
@ -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,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector,CurveLiquidityProvider,BatchFillNativeOrdersFeature,IBatchFillNativeOrdersFeature,MultiplexFeature,IMultiplexFeature,OtcOrdersFeature,IOtcOrdersFeature,AvalancheBridgeAdapter,BSCBridgeAdapter,CeloBridgeAdapter,EthereumBridgeAdapter,FantomBridgeAdapter,OptimismBridgeAdapter,PolygonBridgeAdapter",
|
"publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,PositiveSlippageFeeTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,AffiliateFeeTransformer,MetaTransactionsFeature,LogMetadataTransformer,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector,CurveLiquidityProvider,BatchFillNativeOrdersFeature,IBatchFillNativeOrdersFeature,MultiplexFeature,IMultiplexFeature,OtcOrdersFeature,IOtcOrdersFeature,AvalancheBridgeAdapter,BSCBridgeAdapter,CeloBridgeAdapter,EthereumBridgeAdapter,FantomBridgeAdapter,OptimismBridgeAdapter,PolygonBridgeAdapter",
|
||||||
"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/@(AbstractBridgeAdapter|AffiliateFeeTransformer|AvalancheBridgeAdapter|BSCBridgeAdapter|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeProtocols|CeloBridgeAdapter|CurveLiquidityProvider|ERC1155OrdersFeature|ERC165Feature|ERC721OrdersFeature|EthereumBridgeAdapter|FantomBridgeAdapter|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinERC1155Spender|FixinERC721Spender|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC1155OrdersFeature|IERC1155Token|IERC165Feature|IERC20Bridge|IERC20Transformer|IERC721OrdersFeature|IERC721Token|IFeature|IFeeRecipient|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|IPropertyValidator|ISimpleFunctionRegistryFeature|IStaking|ITakerCallback|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC1155OrdersStorage|LibERC20Transformer|LibERC721OrdersStorage|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNFTOrder|LibNFTOrdersRichErrors|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBalancerV2Batch|MixinBancor|MixinBancorV3|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinGMX|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinPlatypus|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NFTOrders|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OptimismBridgeAdapter|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PolygonBridgeAdapter|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFeeRecipient|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC1155Token|TestMintableERC20Token|TestMintableERC721Token|TestMooniswap|TestNFTOrderPresigner|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestPropertyValidator|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json"
|
"abis": "./test/generated-artifacts/@(AbstractBridgeAdapter|AffiliateFeeTransformer|AvalancheBridgeAdapter|BSCBridgeAdapter|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeProtocols|CeloBridgeAdapter|CurveLiquidityProvider|ERC1155OrdersFeature|ERC165Feature|ERC721OrdersFeature|EthereumBridgeAdapter|FantomBridgeAdapter|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinERC1155Spender|FixinERC721Spender|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC1155OrdersFeature|IERC1155Token|IERC165Feature|IERC20Bridge|IERC20Transformer|IERC721OrdersFeature|IERC721Token|IFeature|IFeeRecipient|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|IPropertyValidator|ISimpleFunctionRegistryFeature|IStaking|ITakerCallback|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC1155OrdersStorage|LibERC20Transformer|LibERC721OrdersStorage|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNFTOrder|LibNFTOrdersRichErrors|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBalancerV2Batch|MixinBancor|MixinBancorV3|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinGMX|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinPlatypus|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinVelodrome|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NFTOrders|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OptimismBridgeAdapter|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PolygonBridgeAdapter|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFeeRecipient|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC1155Token|TestMintableERC20Token|TestMintableERC721Token|TestMooniswap|TestNFTOrderPresigner|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestPropertyValidator|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -127,6 +127,7 @@ import * as MixinShell from '../test/generated-artifacts/MixinShell.json';
|
|||||||
import * as MixinUniswap from '../test/generated-artifacts/MixinUniswap.json';
|
import * as MixinUniswap from '../test/generated-artifacts/MixinUniswap.json';
|
||||||
import * as MixinUniswapV2 from '../test/generated-artifacts/MixinUniswapV2.json';
|
import * as MixinUniswapV2 from '../test/generated-artifacts/MixinUniswapV2.json';
|
||||||
import * as MixinUniswapV3 from '../test/generated-artifacts/MixinUniswapV3.json';
|
import * as MixinUniswapV3 from '../test/generated-artifacts/MixinUniswapV3.json';
|
||||||
|
import * as MixinVelodrome from '../test/generated-artifacts/MixinVelodrome.json';
|
||||||
import * as MixinZeroExBridge from '../test/generated-artifacts/MixinZeroExBridge.json';
|
import * as MixinZeroExBridge from '../test/generated-artifacts/MixinZeroExBridge.json';
|
||||||
import * as MooniswapLiquidityProvider from '../test/generated-artifacts/MooniswapLiquidityProvider.json';
|
import * as MooniswapLiquidityProvider from '../test/generated-artifacts/MooniswapLiquidityProvider.json';
|
||||||
import * as MultiplexFeature from '../test/generated-artifacts/MultiplexFeature.json';
|
import * as MultiplexFeature from '../test/generated-artifacts/MultiplexFeature.json';
|
||||||
@ -349,6 +350,7 @@ export const artifacts = {
|
|||||||
MixinUniswap: MixinUniswap as ContractArtifact,
|
MixinUniswap: MixinUniswap as ContractArtifact,
|
||||||
MixinUniswapV2: MixinUniswapV2 as ContractArtifact,
|
MixinUniswapV2: MixinUniswapV2 as ContractArtifact,
|
||||||
MixinUniswapV3: MixinUniswapV3 as ContractArtifact,
|
MixinUniswapV3: MixinUniswapV3 as ContractArtifact,
|
||||||
|
MixinVelodrome: MixinVelodrome as ContractArtifact,
|
||||||
MixinZeroExBridge: MixinZeroExBridge as ContractArtifact,
|
MixinZeroExBridge: MixinZeroExBridge as ContractArtifact,
|
||||||
IERC1155Token: IERC1155Token as ContractArtifact,
|
IERC1155Token: IERC1155Token as ContractArtifact,
|
||||||
IERC721Token: IERC721Token as ContractArtifact,
|
IERC721Token: IERC721Token as ContractArtifact,
|
||||||
|
@ -125,6 +125,7 @@ export * from '../test/generated-wrappers/mixin_shell';
|
|||||||
export * from '../test/generated-wrappers/mixin_uniswap';
|
export * from '../test/generated-wrappers/mixin_uniswap';
|
||||||
export * from '../test/generated-wrappers/mixin_uniswap_v2';
|
export * from '../test/generated-wrappers/mixin_uniswap_v2';
|
||||||
export * from '../test/generated-wrappers/mixin_uniswap_v3';
|
export * from '../test/generated-wrappers/mixin_uniswap_v3';
|
||||||
|
export * from '../test/generated-wrappers/mixin_velodrome';
|
||||||
export * from '../test/generated-wrappers/mixin_zero_ex_bridge';
|
export * from '../test/generated-wrappers/mixin_zero_ex_bridge';
|
||||||
export * from '../test/generated-wrappers/mooniswap_liquidity_provider';
|
export * from '../test/generated-wrappers/mooniswap_liquidity_provider';
|
||||||
export * from '../test/generated-wrappers/multiplex_feature';
|
export * from '../test/generated-wrappers/multiplex_feature';
|
||||||
|
@ -164,6 +164,7 @@
|
|||||||
"test/generated-artifacts/MixinUniswap.json",
|
"test/generated-artifacts/MixinUniswap.json",
|
||||||
"test/generated-artifacts/MixinUniswapV2.json",
|
"test/generated-artifacts/MixinUniswapV2.json",
|
||||||
"test/generated-artifacts/MixinUniswapV3.json",
|
"test/generated-artifacts/MixinUniswapV3.json",
|
||||||
|
"test/generated-artifacts/MixinVelodrome.json",
|
||||||
"test/generated-artifacts/MixinZeroExBridge.json",
|
"test/generated-artifacts/MixinZeroExBridge.json",
|
||||||
"test/generated-artifacts/MooniswapLiquidityProvider.json",
|
"test/generated-artifacts/MooniswapLiquidityProvider.json",
|
||||||
"test/generated-artifacts/MultiplexFeature.json",
|
"test/generated-artifacts/MultiplexFeature.json",
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
{
|
{
|
||||||
"note": "Add KnightSwap on BSC",
|
"note": "Add KnightSwap on BSC",
|
||||||
"pr": 498
|
"pr": 498
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add Velodrome support on Optimism",
|
||||||
|
"pr": 494
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -44,6 +44,7 @@ import "./TwoHopSampler.sol";
|
|||||||
import "./UniswapSampler.sol";
|
import "./UniswapSampler.sol";
|
||||||
import "./UniswapV2Sampler.sol";
|
import "./UniswapV2Sampler.sol";
|
||||||
import "./UniswapV3Sampler.sol";
|
import "./UniswapV3Sampler.sol";
|
||||||
|
import "./VelodromeSampler.sol";
|
||||||
import "./UtilitySampler.sol";
|
import "./UtilitySampler.sol";
|
||||||
|
|
||||||
|
|
||||||
@ -72,6 +73,7 @@ contract ERC20BridgeSampler is
|
|||||||
UniswapSampler,
|
UniswapSampler,
|
||||||
UniswapV2Sampler,
|
UniswapV2Sampler,
|
||||||
UniswapV3Sampler,
|
UniswapV3Sampler,
|
||||||
|
VelodromeSampler,
|
||||||
UtilitySampler
|
UtilitySampler
|
||||||
{
|
{
|
||||||
|
|
||||||
|
134
packages/asset-swapper/contracts/src/VelodromeSampler.sol
Normal file
134
packages/asset-swapper/contracts/src/VelodromeSampler.sol
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2022 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;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import './ApproximateBuys.sol';
|
||||||
|
import './SamplerUtils.sol';
|
||||||
|
|
||||||
|
struct VeloRoute {
|
||||||
|
address from;
|
||||||
|
address to;
|
||||||
|
bool stable;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IVelodromeRouter {
|
||||||
|
function getAmountOut(
|
||||||
|
uint256 amountIn,
|
||||||
|
address tokenIn,
|
||||||
|
address tokenOut
|
||||||
|
) external view returns (uint256 amount, bool stable);
|
||||||
|
|
||||||
|
function getAmountsOut(uint256 amountIn, VeloRoute[] calldata routes)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (uint256[] memory amounts);
|
||||||
|
}
|
||||||
|
|
||||||
|
contract VelodromeSampler is SamplerUtils, ApproximateBuys {
|
||||||
|
/// @dev Sample sell quotes from Velodrome
|
||||||
|
/// @param router Address of Velodrome router.
|
||||||
|
/// @param takerToken Address of the taker token (what to sell).
|
||||||
|
/// @param makerToken Address of the maker token (what to buy).
|
||||||
|
/// @param takerTokenAmounts Taker token sell amount for each sample (sorted in ascending order).
|
||||||
|
/// @return stable Whether the pool is a stable pool (vs volatile).
|
||||||
|
/// @return makerTokenAmounts Maker amounts bought at each taker token amount.
|
||||||
|
function sampleSellsFromVelodrome(
|
||||||
|
IVelodromeRouter router,
|
||||||
|
address takerToken,
|
||||||
|
address makerToken,
|
||||||
|
uint256[] memory takerTokenAmounts
|
||||||
|
) public view returns (bool stable, uint256[] memory makerTokenAmounts) {
|
||||||
|
_assertValidPair(makerToken, takerToken);
|
||||||
|
uint256 numSamples = takerTokenAmounts.length;
|
||||||
|
makerTokenAmounts = new uint256[](numSamples);
|
||||||
|
|
||||||
|
// Sampling should not mix stable and volatile pools.
|
||||||
|
// Find the most liquid pool based on max(takerTokenAmounts) and stick with it.
|
||||||
|
stable = _isMostLiquidPoolStablePool(router, takerToken, makerToken, takerTokenAmounts);
|
||||||
|
VeloRoute[] memory routes = new VeloRoute[](1);
|
||||||
|
routes[0] = VeloRoute({ from: takerToken, to: makerToken, stable: stable });
|
||||||
|
|
||||||
|
for (uint256 i = 0; i < numSamples; i++) {
|
||||||
|
makerTokenAmounts[i] = router.getAmountsOut(takerTokenAmounts[i], routes)[1];
|
||||||
|
// Break early if there are 0 amounts
|
||||||
|
if (makerTokenAmounts[i] == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Sample buy quotes from Velodrome.
|
||||||
|
/// @param router Address of Velodrome router.
|
||||||
|
/// @param takerToken Address of the taker token (what to sell).
|
||||||
|
/// @param makerToken Address of the maker token (what to buy).
|
||||||
|
/// @param makerTokenAmounts Maker token buy amount for each sample.
|
||||||
|
/// @return stable Whether the pool is a stable pool (vs volatile).
|
||||||
|
/// @return takerTokenAmounts Taker amounts sold at each maker token amount.
|
||||||
|
function sampleBuysFromVelodrome(
|
||||||
|
IVelodromeRouter router,
|
||||||
|
address takerToken,
|
||||||
|
address makerToken,
|
||||||
|
uint256[] memory makerTokenAmounts
|
||||||
|
) public view returns (bool stable, uint256[] memory takerTokenAmounts) {
|
||||||
|
_assertValidPair(makerToken, takerToken);
|
||||||
|
|
||||||
|
// Sampling should not mix stable and volatile pools.
|
||||||
|
// Find the most liquid pool based on the reverse swap (maker -> taker) and stick with it.
|
||||||
|
stable = _isMostLiquidPoolStablePool(router, makerToken, takerToken, makerTokenAmounts);
|
||||||
|
|
||||||
|
takerTokenAmounts = _sampleApproximateBuys(
|
||||||
|
ApproximateBuyQuoteOpts({
|
||||||
|
takerTokenData: abi.encode(router, VeloRoute({ from: takerToken, to: makerToken, stable: stable })),
|
||||||
|
makerTokenData: abi.encode(router, VeloRoute({ from: makerToken, to: takerToken, stable: stable })),
|
||||||
|
getSellQuoteCallback: _sampleSellForApproximateBuyFromVelodrome
|
||||||
|
}),
|
||||||
|
makerTokenAmounts
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _sampleSellForApproximateBuyFromVelodrome(
|
||||||
|
bytes memory takerTokenData,
|
||||||
|
bytes memory, /* makerTokenData */
|
||||||
|
uint256 sellAmount
|
||||||
|
) internal view returns (uint256) {
|
||||||
|
(IVelodromeRouter router, VeloRoute memory route) = abi.decode(takerTokenData, (IVelodromeRouter, VeloRoute));
|
||||||
|
|
||||||
|
VeloRoute[] memory routes = new VeloRoute[](1);
|
||||||
|
routes[0] = route;
|
||||||
|
return router.getAmountsOut(sellAmount, routes)[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Returns whether the most liquid pool is a stable pool.
|
||||||
|
/// @param router Address of Velodrome router.
|
||||||
|
/// @param takerToken Address of the taker token (what to sell).
|
||||||
|
/// @param makerToken Address of the maker token (what to buy).
|
||||||
|
/// @param takerTokenAmounts Taker token buy amount for each sample (sorted in ascending order)
|
||||||
|
/// @return stable Whether the pool is a stable pool (vs volatile).
|
||||||
|
function _isMostLiquidPoolStablePool(
|
||||||
|
IVelodromeRouter router,
|
||||||
|
address takerToken,
|
||||||
|
address makerToken,
|
||||||
|
uint256[] memory takerTokenAmounts
|
||||||
|
) internal view returns (bool stable) {
|
||||||
|
uint256 numSamples = takerTokenAmounts.length;
|
||||||
|
(, stable) = router.getAmountOut(takerTokenAmounts[numSamples - 1], takerToken, makerToken);
|
||||||
|
}
|
||||||
|
}
|
@ -40,7 +40,7 @@
|
|||||||
"config": {
|
"config": {
|
||||||
"publicInterfaceContracts": "ERC20BridgeSampler,BalanceChecker,FakeTaker",
|
"publicInterfaceContracts": "ERC20BridgeSampler,BalanceChecker,FakeTaker",
|
||||||
"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/@(ApproximateBuys|BalanceChecker|BalancerSampler|BalancerV2BatchSampler|BalancerV2Common|BalancerV2Sampler|BancorSampler|BancorV3Sampler|CompoundSampler|CurveSampler|DODOSampler|DODOV2Sampler|ERC20BridgeSampler|FakeTaker|GMXSampler|IBalancer|IBalancerV2Vault|IBancor|IBancorV3|ICurve|IGMX|IMStable|IMooniswap|IMultiBridge|IPlatypus|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberDmmSampler|LidoSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|NativeOrderSampler|PlatypusSampler|SamplerUtils|ShellSampler|SmoothySampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV3Sampler|UtilitySampler).json",
|
"abis": "./test/generated-artifacts/@(ApproximateBuys|BalanceChecker|BalancerSampler|BalancerV2BatchSampler|BalancerV2Common|BalancerV2Sampler|BancorSampler|BancorV3Sampler|CompoundSampler|CurveSampler|DODOSampler|DODOV2Sampler|ERC20BridgeSampler|FakeTaker|GMXSampler|IBalancer|IBalancerV2Vault|IBancor|IBancorV3|ICurve|IGMX|IMStable|IMooniswap|IMultiBridge|IPlatypus|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberDmmSampler|LidoSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|NativeOrderSampler|PlatypusSampler|SamplerUtils|ShellSampler|SmoothySampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV3Sampler|UtilitySampler|VelodromeSampler).json",
|
||||||
"postpublish": {
|
"postpublish": {
|
||||||
"assets": []
|
"assets": []
|
||||||
}
|
}
|
||||||
|
@ -214,6 +214,7 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
|
|||||||
ERC20BridgeSource.Curve,
|
ERC20BridgeSource.Curve,
|
||||||
ERC20BridgeSource.CurveV2,
|
ERC20BridgeSource.CurveV2,
|
||||||
ERC20BridgeSource.MultiHop,
|
ERC20BridgeSource.MultiHop,
|
||||||
|
ERC20BridgeSource.Velodrome,
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
new SourceFilters([]),
|
new SourceFilters([]),
|
||||||
@ -362,6 +363,7 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
|
|||||||
ERC20BridgeSource.Curve,
|
ERC20BridgeSource.Curve,
|
||||||
ERC20BridgeSource.CurveV2,
|
ERC20BridgeSource.CurveV2,
|
||||||
ERC20BridgeSource.MultiHop,
|
ERC20BridgeSource.MultiHop,
|
||||||
|
ERC20BridgeSource.Velodrome,
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
new SourceFilters([]),
|
new SourceFilters([]),
|
||||||
@ -2423,6 +2425,13 @@ export const YOSHI_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
|
|||||||
NULL_ADDRESS,
|
NULL_ADDRESS,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const VELODROME_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
|
||||||
|
{
|
||||||
|
[ChainId.Optimism]: '0xa132dab612db5cb9fc9ac426a0cc215a3423f9c9',
|
||||||
|
},
|
||||||
|
NULL_ADDRESS,
|
||||||
|
);
|
||||||
|
|
||||||
export const VIP_ERC20_BRIDGE_SOURCES_BY_CHAIN_ID = valueByChainId<ERC20BridgeSource[]>(
|
export const VIP_ERC20_BRIDGE_SOURCES_BY_CHAIN_ID = valueByChainId<ERC20BridgeSource[]>(
|
||||||
{
|
{
|
||||||
[ChainId.Mainnet]: [
|
[ChainId.Mainnet]: [
|
||||||
@ -2654,6 +2663,11 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
|
|||||||
[ERC20BridgeSource.SpookySwap]: uniswapV2CloneGasSchedule,
|
[ERC20BridgeSource.SpookySwap]: uniswapV2CloneGasSchedule,
|
||||||
[ERC20BridgeSource.Yoshi]: uniswapV2CloneGasSchedule,
|
[ERC20BridgeSource.Yoshi]: uniswapV2CloneGasSchedule,
|
||||||
[ERC20BridgeSource.Beethovenx]: () => 100e3,
|
[ERC20BridgeSource.Beethovenx]: () => 100e3,
|
||||||
|
|
||||||
|
//
|
||||||
|
// Optimism
|
||||||
|
//
|
||||||
|
[ERC20BridgeSource.Velodrome]: () => 160e3,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DEFAULT_FEE_SCHEDULE: Required<FeeSchedule> = { ...DEFAULT_GAS_SCHEDULE };
|
export const DEFAULT_FEE_SCHEDULE: Required<FeeSchedule> = { ...DEFAULT_GAS_SCHEDULE };
|
||||||
|
@ -40,6 +40,7 @@ import {
|
|||||||
UniswapV2FillData,
|
UniswapV2FillData,
|
||||||
UniswapV3FillData,
|
UniswapV3FillData,
|
||||||
UniswapV3PathAmount,
|
UniswapV3PathAmount,
|
||||||
|
VelodromeFillData,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
// tslint:disable completed-docs
|
// tslint:disable completed-docs
|
||||||
@ -214,6 +215,8 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
|
|||||||
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'MeshSwap');
|
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'MeshSwap');
|
||||||
case ERC20BridgeSource.BancorV3:
|
case ERC20BridgeSource.BancorV3:
|
||||||
return encodeBridgeSourceId(BridgeProtocol.BancorV3, 'BancorV3');
|
return encodeBridgeSourceId(BridgeProtocol.BancorV3, 'BancorV3');
|
||||||
|
case ERC20BridgeSource.Velodrome:
|
||||||
|
return encodeBridgeSourceId(BridgeProtocol.Velodrome, 'Velodrome');
|
||||||
default:
|
default:
|
||||||
throw new Error(AggregationError.NoBridgeForSource);
|
throw new Error(AggregationError.NoBridgeForSource);
|
||||||
}
|
}
|
||||||
@ -397,6 +400,10 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
|
|||||||
const bancorV3FillData = (order as OptimizedMarketBridgeOrder<BancorFillData>).fillData;
|
const bancorV3FillData = (order as OptimizedMarketBridgeOrder<BancorFillData>).fillData;
|
||||||
bridgeData = encoder.encode([bancorV3FillData.networkAddress, bancorV3FillData.path]);
|
bridgeData = encoder.encode([bancorV3FillData.networkAddress, bancorV3FillData.path]);
|
||||||
break;
|
break;
|
||||||
|
case ERC20BridgeSource.Velodrome:
|
||||||
|
const velodromeFillData = (order as OptimizedMarketBridgeOrder<VelodromeFillData>).fillData;
|
||||||
|
bridgeData = encoder.encode([velodromeFillData.router, velodromeFillData.stable]);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(AggregationError.NoBridgeForSource);
|
throw new Error(AggregationError.NoBridgeForSource);
|
||||||
}
|
}
|
||||||
@ -590,6 +597,7 @@ export const BRIDGE_ENCODERS: {
|
|||||||
[ERC20BridgeSource.AaveV2]: AbiEncoder.create('(address,address)'),
|
[ERC20BridgeSource.AaveV2]: AbiEncoder.create('(address,address)'),
|
||||||
[ERC20BridgeSource.Compound]: AbiEncoder.create('(address)'),
|
[ERC20BridgeSource.Compound]: AbiEncoder.create('(address)'),
|
||||||
[ERC20BridgeSource.Geist]: AbiEncoder.create('(address,address)'),
|
[ERC20BridgeSource.Geist]: AbiEncoder.create('(address,address)'),
|
||||||
|
[ERC20BridgeSource.Velodrome]: AbiEncoder.create('(address,bool)'),
|
||||||
};
|
};
|
||||||
|
|
||||||
function getFillTokenAmounts(fill: CollapsedFill, side: MarketOperation): [BigNumber, BigNumber] {
|
function getFillTokenAmounts(fill: CollapsedFill, side: MarketOperation): [BigNumber, BigNumber] {
|
||||||
|
@ -48,6 +48,7 @@ import {
|
|||||||
SELL_SOURCE_FILTER_BY_CHAIN_ID,
|
SELL_SOURCE_FILTER_BY_CHAIN_ID,
|
||||||
UNISWAPV1_ROUTER_BY_CHAIN_ID,
|
UNISWAPV1_ROUTER_BY_CHAIN_ID,
|
||||||
UNISWAPV3_CONFIG_BY_CHAIN_ID,
|
UNISWAPV3_CONFIG_BY_CHAIN_ID,
|
||||||
|
VELODROME_ROUTER_BY_CHAIN_ID,
|
||||||
ZERO_AMOUNT,
|
ZERO_AMOUNT,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
import { getGeistInfoForPair } from './geist_utils';
|
import { getGeistInfoForPair } from './geist_utils';
|
||||||
@ -95,6 +96,7 @@ import {
|
|||||||
TokenAdjacencyGraph,
|
TokenAdjacencyGraph,
|
||||||
UniswapV2FillData,
|
UniswapV2FillData,
|
||||||
UniswapV3FillData,
|
UniswapV3FillData,
|
||||||
|
VelodromeFillData,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1301,6 +1303,7 @@ export class SamplerOperations {
|
|||||||
params: [pool[0], tokenAddressPath, takerFillAmounts],
|
params: [pool[0], tokenAddressPath, takerFillAmounts],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public getPlatypusBuyQuotes(
|
public getPlatypusBuyQuotes(
|
||||||
router: string,
|
router: string,
|
||||||
pool: string[],
|
pool: string[],
|
||||||
@ -1316,6 +1319,52 @@ export class SamplerOperations {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getVelodromeSellQuotes(
|
||||||
|
router: string,
|
||||||
|
takerToken: string,
|
||||||
|
makerToken: string,
|
||||||
|
takerFillAmounts: BigNumber[],
|
||||||
|
): SourceQuoteOperation<VelodromeFillData> {
|
||||||
|
return new SamplerContractOperation({
|
||||||
|
source: ERC20BridgeSource.Velodrome,
|
||||||
|
contract: this._samplerContract,
|
||||||
|
function: this._samplerContract.sampleSellsFromVelodrome,
|
||||||
|
params: [router, takerToken, makerToken, takerFillAmounts],
|
||||||
|
callback: (callResults: string, fillData: VelodromeFillData): BigNumber[] => {
|
||||||
|
const [isStable, samples] = this._samplerContract.getABIDecodedReturnData<[boolean, BigNumber[]]>(
|
||||||
|
'sampleSellsFromVelodrome',
|
||||||
|
callResults,
|
||||||
|
);
|
||||||
|
fillData.router = router;
|
||||||
|
fillData.stable = isStable;
|
||||||
|
return samples;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getVelodromeBuyQuotes(
|
||||||
|
router: string,
|
||||||
|
takerToken: string,
|
||||||
|
makerToken: string,
|
||||||
|
makerFillAmounts: BigNumber[],
|
||||||
|
): SourceQuoteOperation<VelodromeFillData> {
|
||||||
|
return new SamplerContractOperation({
|
||||||
|
source: ERC20BridgeSource.Velodrome,
|
||||||
|
contract: this._samplerContract,
|
||||||
|
function: this._samplerContract.sampleBuysFromVelodrome,
|
||||||
|
params: [router, takerToken, makerToken, makerFillAmounts],
|
||||||
|
callback: (callResults: string, fillData: VelodromeFillData): BigNumber[] => {
|
||||||
|
const [isStable, samples] = this._samplerContract.getABIDecodedReturnData<[boolean, BigNumber[]]>(
|
||||||
|
'sampleBuysFromVelodrome',
|
||||||
|
callResults,
|
||||||
|
);
|
||||||
|
fillData.router = router;
|
||||||
|
fillData.stable = isStable;
|
||||||
|
return samples;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public getMedianSellRate(
|
public getMedianSellRate(
|
||||||
sources: ERC20BridgeSource[],
|
sources: ERC20BridgeSource[],
|
||||||
makerToken: string,
|
makerToken: string,
|
||||||
@ -1719,6 +1768,14 @@ export class SamplerOperations {
|
|||||||
takerFillAmounts,
|
takerFillAmounts,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
case ERC20BridgeSource.Velodrome: {
|
||||||
|
return this.getVelodromeSellQuotes(
|
||||||
|
VELODROME_ROUTER_BY_CHAIN_ID[this.chainId],
|
||||||
|
takerToken,
|
||||||
|
makerToken,
|
||||||
|
takerFillAmounts,
|
||||||
|
);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unsupported sell sample source: ${source}`);
|
throw new Error(`Unsupported sell sample source: ${source}`);
|
||||||
}
|
}
|
||||||
@ -2057,6 +2114,14 @@ export class SamplerOperations {
|
|||||||
makerFillAmounts,
|
makerFillAmounts,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
case ERC20BridgeSource.Velodrome: {
|
||||||
|
return this.getVelodromeBuyQuotes(
|
||||||
|
VELODROME_ROUTER_BY_CHAIN_ID[this.chainId],
|
||||||
|
takerToken,
|
||||||
|
makerToken,
|
||||||
|
makerFillAmounts,
|
||||||
|
);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unsupported buy sample source: ${source}`);
|
throw new Error(`Unsupported buy sample source: ${source}`);
|
||||||
}
|
}
|
||||||
|
@ -108,6 +108,8 @@ export enum ERC20BridgeSource {
|
|||||||
MorpheusSwap = 'MorpheusSwap',
|
MorpheusSwap = 'MorpheusSwap',
|
||||||
Yoshi = 'Yoshi',
|
Yoshi = 'Yoshi',
|
||||||
Geist = 'Geist',
|
Geist = 'Geist',
|
||||||
|
// Optimism
|
||||||
|
Velodrome = 'Velodrome',
|
||||||
}
|
}
|
||||||
export type SourcesWithPoolsCache =
|
export type SourcesWithPoolsCache =
|
||||||
| ERC20BridgeSource.Balancer
|
| ERC20BridgeSource.Balancer
|
||||||
@ -378,6 +380,12 @@ export interface PlatypusFillData extends FillData {
|
|||||||
pool: string[];
|
pool: string[];
|
||||||
tokenAddressPath: string[];
|
tokenAddressPath: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface VelodromeFillData extends FillData {
|
||||||
|
router: string;
|
||||||
|
stable: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a node on a fill path.
|
* Represents a node on a fill path.
|
||||||
*/
|
*/
|
||||||
|
@ -51,6 +51,7 @@ import * as UniswapSampler from '../test/generated-artifacts/UniswapSampler.json
|
|||||||
import * as UniswapV2Sampler from '../test/generated-artifacts/UniswapV2Sampler.json';
|
import * as UniswapV2Sampler from '../test/generated-artifacts/UniswapV2Sampler.json';
|
||||||
import * as UniswapV3Sampler from '../test/generated-artifacts/UniswapV3Sampler.json';
|
import * as UniswapV3Sampler from '../test/generated-artifacts/UniswapV3Sampler.json';
|
||||||
import * as UtilitySampler from '../test/generated-artifacts/UtilitySampler.json';
|
import * as UtilitySampler from '../test/generated-artifacts/UtilitySampler.json';
|
||||||
|
import * as VelodromeSampler from '../test/generated-artifacts/VelodromeSampler.json';
|
||||||
export const artifacts = {
|
export const artifacts = {
|
||||||
ApproximateBuys: ApproximateBuys as ContractArtifact,
|
ApproximateBuys: ApproximateBuys as ContractArtifact,
|
||||||
BalanceChecker: BalanceChecker as ContractArtifact,
|
BalanceChecker: BalanceChecker as ContractArtifact,
|
||||||
@ -83,6 +84,7 @@ export const artifacts = {
|
|||||||
UniswapV2Sampler: UniswapV2Sampler as ContractArtifact,
|
UniswapV2Sampler: UniswapV2Sampler as ContractArtifact,
|
||||||
UniswapV3Sampler: UniswapV3Sampler as ContractArtifact,
|
UniswapV3Sampler: UniswapV3Sampler as ContractArtifact,
|
||||||
UtilitySampler: UtilitySampler as ContractArtifact,
|
UtilitySampler: UtilitySampler as ContractArtifact,
|
||||||
|
VelodromeSampler: VelodromeSampler as ContractArtifact,
|
||||||
IBalancer: IBalancer as ContractArtifact,
|
IBalancer: IBalancer as ContractArtifact,
|
||||||
IBalancerV2Vault: IBalancerV2Vault as ContractArtifact,
|
IBalancerV2Vault: IBalancerV2Vault as ContractArtifact,
|
||||||
IBancor: IBancor as ContractArtifact,
|
IBancor: IBancor as ContractArtifact,
|
||||||
|
@ -49,3 +49,4 @@ export * from '../test/generated-wrappers/uniswap_sampler';
|
|||||||
export * from '../test/generated-wrappers/uniswap_v2_sampler';
|
export * from '../test/generated-wrappers/uniswap_v2_sampler';
|
||||||
export * from '../test/generated-wrappers/uniswap_v3_sampler';
|
export * from '../test/generated-wrappers/uniswap_v3_sampler';
|
||||||
export * from '../test/generated-wrappers/utility_sampler';
|
export * from '../test/generated-wrappers/utility_sampler';
|
||||||
|
export * from '../test/generated-wrappers/velodrome_sampler';
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
"test/generated-artifacts/UniswapSampler.json",
|
"test/generated-artifacts/UniswapSampler.json",
|
||||||
"test/generated-artifacts/UniswapV2Sampler.json",
|
"test/generated-artifacts/UniswapV2Sampler.json",
|
||||||
"test/generated-artifacts/UniswapV3Sampler.json",
|
"test/generated-artifacts/UniswapV3Sampler.json",
|
||||||
"test/generated-artifacts/UtilitySampler.json"
|
"test/generated-artifacts/UtilitySampler.json",
|
||||||
|
"test/generated-artifacts/VelodromeSampler.json"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "11.15.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Add Velodrome support",
|
||||||
|
"pr": 494
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "11.14.0",
|
"version": "11.14.0",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
@ -139,6 +139,7 @@ export enum BridgeProtocol {
|
|||||||
GMX,
|
GMX,
|
||||||
Platypus,
|
Platypus,
|
||||||
BancorV3,
|
BancorV3,
|
||||||
|
Velodrome,
|
||||||
}
|
}
|
||||||
// tslint:enable: enum-naming
|
// tslint:enable: enum-naming
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user