From 43e3dce9651718e542a0f50f8a23de229c0ca04d Mon Sep 17 00:00:00 2001 From: "Savarn Dontamsetti (Sav)" Date: Tue, 8 Aug 2023 16:20:03 -0400 Subject: [PATCH] Adding support for Velodrome V2 on Optimism (#739) * Adding support for Velodrome V2 for Optimism --- contracts/zero-ex/CHANGELOG.json | 8 +++ .../transformers/bridges/BridgeProtocols.sol | 1 + .../bridges/OptimismBridgeAdapter.sol | 7 ++ .../bridges/mixins/MixinVelodromeV2.sol | 69 +++++++++++++++++++ packages/contract-addresses/CHANGELOG.json | 8 +++ packages/contract-addresses/addresses.json | 2 +- packages/protocol-utils/CHANGELOG.json | 8 +++ .../protocol-utils/src/transformer_utils.ts | 1 + 8 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 contracts/zero-ex/contracts/src/transformers/bridges/mixins/MixinVelodromeV2.sol diff --git a/contracts/zero-ex/CHANGELOG.json b/contracts/zero-ex/CHANGELOG.json index 771ad0a974..fd3c28549e 100644 --- a/contracts/zero-ex/CHANGELOG.json +++ b/contracts/zero-ex/CHANGELOG.json @@ -1,4 +1,12 @@ [ + { + "version": "0.46.0", + "changes": [ + { + "note": "Add VelodromeV2 support on Optimism" + } + ] + }, { "timestamp": 1689974915, "version": "0.45.1", diff --git a/contracts/zero-ex/contracts/src/transformers/bridges/BridgeProtocols.sol b/contracts/zero-ex/contracts/src/transformers/bridges/BridgeProtocols.sol index 85e5897219..df9e69a9f9 100644 --- a/contracts/zero-ex/contracts/src/transformers/bridges/BridgeProtocols.sol +++ b/contracts/zero-ex/contracts/src/transformers/bridges/BridgeProtocols.sol @@ -57,4 +57,5 @@ library BridgeProtocols { uint128 internal constant KYBERELASTIC = 33; uint128 internal constant BARTER = 34; uint128 internal constant TRADERJOEV2 = 35; + uint128 internal constant VELODROMEV2 = 36; } diff --git a/contracts/zero-ex/contracts/src/transformers/bridges/OptimismBridgeAdapter.sol b/contracts/zero-ex/contracts/src/transformers/bridges/OptimismBridgeAdapter.sol index 224dd6f9d4..82081a15ca 100644 --- a/contracts/zero-ex/contracts/src/transformers/bridges/OptimismBridgeAdapter.sol +++ b/contracts/zero-ex/contracts/src/transformers/bridges/OptimismBridgeAdapter.sol @@ -26,6 +26,7 @@ import "./mixins/MixinNerve.sol"; import "./mixins/MixinSolidly.sol"; import "./mixins/MixinSynthetix.sol"; import "./mixins/MixinUniswapV3.sol"; +import "./mixins/MixinVelodromeV2.sol"; import "./mixins/MixinWOOFi.sol"; import "./mixins/MixinZeroExBridge.sol"; @@ -39,6 +40,7 @@ contract OptimismBridgeAdapter is MixinNerve, MixinSynthetix, MixinUniswapV3, + MixinVelodromeV2, MixinSolidly, MixinWOOFi, MixinZeroExBridge @@ -109,6 +111,11 @@ contract OptimismBridgeAdapter is return (0, true); } boughtAmount = _tradeKyberElastic(sellToken, sellAmount, order.bridgeData); + } else if (protocolId == BridgeProtocols.VELODROMEV2) { + if (dryRun) { + return (0, true); + } + boughtAmount = _tradeVelodromeV2(sellToken, sellAmount, order.bridgeData); } emit BridgeFill(order.source, sellToken, buyToken, sellAmount, boughtAmount); diff --git a/contracts/zero-ex/contracts/src/transformers/bridges/mixins/MixinVelodromeV2.sol b/contracts/zero-ex/contracts/src/transformers/bridges/mixins/MixinVelodromeV2.sol new file mode 100644 index 0000000000..baa34ccc92 --- /dev/null +++ b/contracts/zero-ex/contracts/src/transformers/bridges/mixins/MixinVelodromeV2.sol @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: Apache-2.0 +/* + Copyright 2023 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/src/v06/LibERC20TokenV06.sol"; +import "@0x/contracts-erc20/src/IERC20Token.sol"; + +interface IVelodromeV2Router { + struct Route { + address from; + address to; + bool stable; + address factory; + } + + /// @notice Swap one token for another + /// @param amountIn Amount of token in + /// @param amountOutMin Minimum amount of desired token received + /// @param routes Array of trade routes used in the swap + /// @param to Recipient of the tokens received + /// @param deadline Deadline to receive tokens + /// @return amounts Array of amounts returned per route + function swapExactTokensForTokens( + uint256 amountIn, + uint256 amountOutMin, + Route[] calldata routes, + address to, + uint256 deadline + ) external returns (uint256[] memory amounts); +} + +contract MixinVelodromeV2 { + using LibERC20TokenV06 for IERC20Token; + + function _tradeVelodromeV2( + IERC20Token sellToken, + uint256 sellAmount, + bytes memory bridgeData + ) internal returns (uint256 boughtAmount) { + (IVelodromeV2Router router, IVelodromeV2Router.Route[] memory routes) = abi.decode( + bridgeData, + (IVelodromeV2Router, IVelodromeV2Router.Route[]) + ); + sellToken.approveIfBelow(address(router), sellAmount); + + uint256[] memory amounts = router.swapExactTokensForTokens( + sellAmount, + 1, + routes, + address(this), + block.timestamp + 1 + ); + + return amounts[amounts.length - 1]; + } +} diff --git a/packages/contract-addresses/CHANGELOG.json b/packages/contract-addresses/CHANGELOG.json index e759b9196d..487ffcde4f 100644 --- a/packages/contract-addresses/CHANGELOG.json +++ b/packages/contract-addresses/CHANGELOG.json @@ -1,4 +1,12 @@ [ + { + "version": "8.10.0", + "changes": [ + { + "note": "Add VelodromeV2 support on Optimism" + } + ] + }, { "version": "8.9.0", "changes": [ diff --git a/packages/contract-addresses/addresses.json b/packages/contract-addresses/addresses.json index 552efc4e41..8c22c0f1ea 100644 --- a/packages/contract-addresses/addresses.json +++ b/packages/contract-addresses/addresses.json @@ -225,7 +225,7 @@ "wethTransformer": "0x02ce7af6520e2862f961f5d7eda746642865179c", "payTakerTransformer": "0xa6c3ca183a67fcb4299fb4199c12ca74874ca489", "affiliateFeeTransformer": "0x3102aea537ecb6f164550b094663c82a8c53a972", - "fillQuoteTransformer": "0xd140adb61d4e3e3978d4f32ac6b92240ff6e3a6e", + "fillQuoteTransformer": "0x521f3184ab27abde4a34e744a908b1a08dc8ef91", "positiveSlippageFeeTransformer": "0x9a4947d3fb77a7afc2c9cd6714bbae96dddde059" } }, diff --git a/packages/protocol-utils/CHANGELOG.json b/packages/protocol-utils/CHANGELOG.json index 9dce6df132..d8c7c835c3 100644 --- a/packages/protocol-utils/CHANGELOG.json +++ b/packages/protocol-utils/CHANGELOG.json @@ -1,4 +1,12 @@ [ + { + "version": "11.23.0", + "changes": [ + { + "note": "Add VelodromeV2 support on Optimism" + } + ] + }, { "timestamp": 1689974915, "version": "11.22.4", diff --git a/packages/protocol-utils/src/transformer_utils.ts b/packages/protocol-utils/src/transformer_utils.ts index ec875941da..c6f9e5fcb3 100644 --- a/packages/protocol-utils/src/transformer_utils.ts +++ b/packages/protocol-utils/src/transformer_utils.ts @@ -166,6 +166,7 @@ export enum BridgeProtocol { KyberElastic, Barter, TraderJoeV2, + VelodromeV2, } /**