Use delegatecall to break up EthereumBridgeAdapter

This commit is contained in:
Michael Zhu
2022-05-24 14:01:05 -07:00
parent a380bdb843
commit 996dd0c487
14 changed files with 111 additions and 45 deletions

View File

@@ -20,16 +20,9 @@
pragma solidity ^0.6.5;
pragma experimental ABIEncoderV2;
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
import "./IBridgeAdapter.sol";
import "./BridgeProtocols.sol";
import "./mixins/MixinAaveV2.sol";
import "./mixins/MixinBalancer.sol";
import "./mixins/MixinBalancerV2.sol";
import "./mixins/MixinBalancerV2Batch.sol";
import "./mixins/MixinBancor.sol";
import "./mixins/MixinCompound.sol";
import "./mixins/MixinCurve.sol";
import "./mixins/MixinCurveV2.sol";
import "./mixins/MixinCryptoCom.sol";
import "./mixins/MixinDodo.sol";
import "./mixins/MixinDodoV2.sol";
@@ -43,17 +36,10 @@ import "./mixins/MixinUniswap.sol";
import "./mixins/MixinUniswapV2.sol";
import "./mixins/MixinUniswapV3.sol";
import "./mixins/MixinZeroExBridge.sol";
import "./EthereumSubAdapter1.sol";
contract EthereumBridgeAdapter is
IBridgeAdapter,
MixinAaveV2,
MixinBalancer,
MixinBalancerV2,
MixinBalancerV2Batch,
MixinBancor,
MixinCompound,
MixinCurve,
MixinCurveV2,
MixinCryptoCom,
MixinDodo,
MixinDodoV2,
@@ -68,11 +54,12 @@ contract EthereumBridgeAdapter is
MixinUniswapV3,
MixinZeroExBridge
{
constructor(IEtherTokenV06 weth)
using LibRichErrorsV06 for bytes;
EthereumSubAdapter1 private immutable _subadapter1;
constructor(IEtherTokenV06 weth, EthereumSubAdapter1 subadapter1)
public
MixinBancor(weth)
MixinCompound(weth)
MixinCurve(weth)
MixinLido(weth)
MixinMooniswap(weth)
MixinUniswap(weth)
@@ -81,6 +68,8 @@ contract EthereumBridgeAdapter is
assembly { chainId := chainid() }
// Allow Ganache for testing
require(chainId == 1 || chainId == 1337 , 'EthereumBridgeAdapter.constructor: wrong chain ID');
_subadapter1 = subadapter1;
}
function trade(
@@ -95,19 +84,21 @@ contract EthereumBridgeAdapter is
{
uint128 protocolId = uint128(uint256(order.source) >> 128);
if (protocolId == BridgeProtocols.CURVE) {
boughtAmount = _tradeCurve(
boughtAmount = _delegateCallSubAdapter(address(_subadapter1), abi.encodeWithSelector(
_subadapter1._tradeCurve.selector,
sellToken,
buyToken,
sellAmount,
order.bridgeData
);
));
} else if (protocolId == BridgeProtocols.CURVEV2) {
boughtAmount = _tradeCurveV2(
boughtAmount = _delegateCallSubAdapter(address(_subadapter1), abi.encodeWithSelector(
_subadapter1._tradeCurveV2.selector,
sellToken,
buyToken,
sellAmount,
order.bridgeData
);
));
} else if (protocolId == BridgeProtocols.UNISWAPV3) {
boughtAmount = _tradeUniswapV3(
sellToken,
@@ -128,24 +119,27 @@ contract EthereumBridgeAdapter is
order.bridgeData
);
} else if (protocolId == BridgeProtocols.BALANCER) {
boughtAmount = _tradeBalancer(
boughtAmount = _delegateCallSubAdapter(address(_subadapter1), abi.encodeWithSelector(
_subadapter1._tradeBalancer.selector,
sellToken,
buyToken,
sellAmount,
order.bridgeData
);
));
} else if (protocolId == BridgeProtocols.BALANCERV2) {
boughtAmount = _tradeBalancerV2(
boughtAmount = _delegateCallSubAdapter(address(_subadapter1), abi.encodeWithSelector(
_subadapter1._tradeBalancerV2.selector,
sellToken,
buyToken,
sellAmount,
order.bridgeData
);
));
} else if (protocolId == BridgeProtocols.BALANCERV2BATCH) {
boughtAmount = _tradeBalancerV2Batch(
boughtAmount = _delegateCallSubAdapter(address(_subadapter1), abi.encodeWithSelector(
_subadapter1._tradeBalancerV2Batch.selector,
sellAmount,
order.bridgeData
);
));
} else if (protocolId == BridgeProtocols.MAKERPSM) {
boughtAmount = _tradeMakerPsm(
sellToken,
@@ -193,11 +187,12 @@ contract EthereumBridgeAdapter is
order.bridgeData
);
} else if (protocolId == BridgeProtocols.BANCOR) {
boughtAmount = _tradeBancor(
boughtAmount = _delegateCallSubAdapter(address(_subadapter1), abi.encodeWithSelector(
_subadapter1._tradeBancor.selector,
buyToken,
sellAmount,
order.bridgeData
);
));
} else if (protocolId == BridgeProtocols.KYBERDMM) {
boughtAmount = _tradeKyberDmm(
buyToken,
@@ -212,19 +207,21 @@ contract EthereumBridgeAdapter is
order.bridgeData
);
} else if (protocolId == BridgeProtocols.AAVEV2) {
boughtAmount = _tradeAaveV2(
boughtAmount = _delegateCallSubAdapter(address(_subadapter1), abi.encodeWithSelector(
_subadapter1._tradeAaveV2.selector,
sellToken,
buyToken,
sellAmount,
order.bridgeData
);
));
} else if (protocolId == BridgeProtocols.COMPOUND) {
boughtAmount = _tradeCompound(
boughtAmount = _delegateCallSubAdapter(address(_subadapter1), abi.encodeWithSelector(
_subadapter1._tradeCompound.selector,
sellToken,
buyToken,
sellAmount,
order.bridgeData
);
));
} else {
boughtAmount = _tradeZeroExBridge(
sellToken,
@@ -242,4 +239,17 @@ contract EthereumBridgeAdapter is
boughtAmount
);
}
function _delegateCallSubAdapter(address subadapter, bytes memory encodedCall)
private
returns (uint256 boughtAmount)
{
(bool success, bytes memory resultData) = address(subadapter)
.delegatecall(encodedCall);
if (!success) {
resultData.rrevert();
} else {
boughtAmount = abi.decode(resultData, (uint256));
}
}
}

View File

@@ -0,0 +1,52 @@
// 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 "./mixins/MixinAaveV2.sol";
import "./mixins/MixinBalancer.sol";
import "./mixins/MixinBalancerV2.sol";
import "./mixins/MixinBalancerV2Batch.sol";
import "./mixins/MixinBancor.sol";
import "./mixins/MixinCompound.sol";
import "./mixins/MixinCurve.sol";
import "./mixins/MixinCurveV2.sol";
contract EthereumSubAdapter1 is
MixinAaveV2,
MixinBalancer,
MixinBalancerV2,
MixinBalancerV2Batch,
MixinBancor,
MixinCompound,
MixinCurve,
MixinCurveV2
{
constructor(IEtherTokenV06 weth)
public
MixinBancor(weth)
MixinCompound(weth)
MixinCurve(weth)
{
uint256 chainId;
assembly { chainId := chainid() }
require(chainId == 1, 'EthereumSubAdapter1.constructor: wrong chain ID');
}
}

View File

@@ -70,7 +70,7 @@ contract MixinAaveV2 {
uint256 sellAmount,
bytes memory bridgeData
)
internal
public
returns (uint256)
{
(ILendingPool lendingPool, address aToken) = abi.decode(bridgeData, (ILendingPool, address));

View File

@@ -51,7 +51,7 @@ contract MixinBalancer {
uint256 sellAmount,
bytes memory bridgeData
)
internal
public
returns (uint256 boughtAmount)
{
// Decode the bridge data.

View File

@@ -80,7 +80,7 @@ contract MixinBalancerV2 {
uint256 sellAmount,
bytes memory bridgeData
)
internal
public
returns (uint256 boughtAmount)
{
// Decode the bridge data.

View File

@@ -67,7 +67,7 @@ contract MixinBalancerV2Batch {
uint256 sellAmount,
bytes memory bridgeData
)
internal
public
returns (uint256 boughtAmount)
{
// Decode the bridge data.

View File

@@ -60,7 +60,7 @@ contract MixinBancor {
uint256 sellAmount,
bytes memory bridgeData
)
internal
public
returns (uint256 boughtAmount)
{
// Decode the bridge data.

View File

@@ -67,7 +67,7 @@ contract MixinCompound {
uint256 sellAmount,
bytes memory bridgeData
)
internal
public
returns (uint256)
{
(address cTokenAddress) = abi.decode(bridgeData, (address));

View File

@@ -55,7 +55,7 @@ contract MixinCurve {
uint256 sellAmount,
bytes memory bridgeData
)
internal
public
returns (uint256 boughtAmount)
{
// Decode the bridge data to get the Curve metadata.

View File

@@ -44,7 +44,7 @@ contract MixinCurveV2 {
uint256 sellAmount,
bytes memory bridgeData
)
internal
public
returns (uint256 boughtAmount)
{
// Decode the bridge data to get the Curve metadata.

View File

@@ -43,7 +43,7 @@
"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",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
"abis": "./test/generated-artifacts/@(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|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/@(AffiliateFeeTransformer|AvalancheBridgeAdapter|BSCBridgeAdapter|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeProtocols|CeloBridgeAdapter|CurveLiquidityProvider|ERC1155OrdersFeature|ERC165Feature|ERC721OrdersFeature|EthereumBridgeAdapter|EthereumSubAdapter1|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|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"
},
"repository": {
"type": "git",

View File

@@ -17,6 +17,7 @@ import * as ERC1155OrdersFeature from '../test/generated-artifacts/ERC1155Orders
import * as ERC165Feature from '../test/generated-artifacts/ERC165Feature.json';
import * as ERC721OrdersFeature from '../test/generated-artifacts/ERC721OrdersFeature.json';
import * as EthereumBridgeAdapter from '../test/generated-artifacts/EthereumBridgeAdapter.json';
import * as EthereumSubAdapter1 from '../test/generated-artifacts/EthereumSubAdapter1.json';
import * as FantomBridgeAdapter from '../test/generated-artifacts/FantomBridgeAdapter.json';
import * as FeeCollector from '../test/generated-artifacts/FeeCollector.json';
import * as FeeCollectorController from '../test/generated-artifacts/FeeCollectorController.json';
@@ -318,6 +319,7 @@ export const artifacts = {
BridgeProtocols: BridgeProtocols as ContractArtifact,
CeloBridgeAdapter: CeloBridgeAdapter as ContractArtifact,
EthereumBridgeAdapter: EthereumBridgeAdapter as ContractArtifact,
EthereumSubAdapter1: EthereumSubAdapter1 as ContractArtifact,
FantomBridgeAdapter: FantomBridgeAdapter as ContractArtifact,
IBridgeAdapter: IBridgeAdapter as ContractArtifact,
OptimismBridgeAdapter: OptimismBridgeAdapter as ContractArtifact,

View File

@@ -15,6 +15,7 @@ export * from '../test/generated-wrappers/erc1155_orders_feature';
export * from '../test/generated-wrappers/erc165_feature';
export * from '../test/generated-wrappers/erc721_orders_feature';
export * from '../test/generated-wrappers/ethereum_bridge_adapter';
export * from '../test/generated-wrappers/ethereum_sub_adapter1';
export * from '../test/generated-wrappers/fantom_bridge_adapter';
export * from '../test/generated-wrappers/fee_collector';
export * from '../test/generated-wrappers/fee_collector_controller';

View File

@@ -54,6 +54,7 @@
"test/generated-artifacts/ERC165Feature.json",
"test/generated-artifacts/ERC721OrdersFeature.json",
"test/generated-artifacts/EthereumBridgeAdapter.json",
"test/generated-artifacts/EthereumSubAdapter1.json",
"test/generated-artifacts/FantomBridgeAdapter.json",
"test/generated-artifacts/FeeCollector.json",
"test/generated-artifacts/FeeCollectorController.json",