From 00f55be83ef3187ddbbf90e026fe96670523cc81 Mon Sep 17 00:00:00 2001 From: Alex Kroeger Date: Tue, 29 Sep 2020 12:59:54 -0700 Subject: [PATCH] Added cream bridge contract --- .../contracts/src/bridges/CreamBridge.sol | 103 ++++++++++++++++++ contracts/asset-proxy/package.json | 2 +- contracts/asset-proxy/src/artifacts.ts | 2 + contracts/asset-proxy/src/wrappers.ts | 1 + contracts/asset-proxy/test/artifacts.ts | 2 + contracts/asset-proxy/test/wrappers.ts | 1 + contracts/asset-proxy/tsconfig.json | 2 + 7 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 contracts/asset-proxy/contracts/src/bridges/CreamBridge.sol diff --git a/contracts/asset-proxy/contracts/src/bridges/CreamBridge.sol b/contracts/asset-proxy/contracts/src/bridges/CreamBridge.sol new file mode 100644 index 0000000000..c1a5750afa --- /dev/null +++ b/contracts/asset-proxy/contracts/src/bridges/CreamBridge.sol @@ -0,0 +1,103 @@ + +/* + + 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.5.9; +pragma experimental ABIEncoderV2; + +import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; +import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol"; +import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol"; +import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; +import "../interfaces/IERC20Bridge.sol"; +import "../interfaces/IBalancerPool.sol"; + + +contract CreamBridge is + IERC20Bridge, + IWallet, + DeploymentConstants +{ + /// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of + /// `toTokenAddress` tokens by selling the entirety of the `fromTokenAddress` + /// token encoded in the bridge data, then transfers the bought + /// tokens to `to`. + /// @param toTokenAddress The token to buy and transfer to `to`. + /// @param from The maker (this contract). + /// @param to The recipient of the bought tokens. + /// @param amount Minimum amount of `toTokenAddress` tokens to buy. + /// @param bridgeData The abi-encoded addresses of the "from" token and Balancer pool. + /// @return success The magic bytes if successful. + function bridgeTransferFrom( + address toTokenAddress, + address from, + address to, + uint256 amount, + bytes calldata bridgeData + ) + external + returns (bytes4 success) + { + // Decode the bridge data. + (address fromTokenAddress, address poolAddress) = abi.decode( + bridgeData, + (address, address) + ); + require(toTokenAddress != fromTokenAddress, "CreamBridge/INVALID_PAIR"); + + uint256 fromTokenBalance = IERC20Token(fromTokenAddress).balanceOf(address(this)); + // Grant an allowance to the exchange to spend `fromTokenAddress` token. + LibERC20Token.approveIfBelow(fromTokenAddress, poolAddress, fromTokenBalance); + + // Sell all of this contract's `fromTokenAddress` token balance. + (uint256 boughtAmount,) = IBalancerPool(poolAddress).swapExactAmountIn( + fromTokenAddress, // tokenIn + fromTokenBalance, // tokenAmountIn + toTokenAddress, // tokenOut + amount, // minAmountOut + uint256(-1) // maxPrice + ); + + // Transfer the converted `toToken`s to `to`. + LibERC20Token.transfer(toTokenAddress, to, boughtAmount); + + emit ERC20BridgeTransfer( + fromTokenAddress, + toTokenAddress, + fromTokenBalance, + boughtAmount, + from, + to + ); + return BRIDGE_SUCCESS; + } + + /// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker + /// and sign for itself in orders. Always succeeds. + /// @return magicValue Magic success bytes, always. + function isValidSignature( + bytes32, + bytes calldata + ) + external + view + returns (bytes4 magicValue) + { + return LEGACY_WALLET_MAGIC_VALUE; + } +} diff --git a/contracts/asset-proxy/package.json b/contracts/asset-proxy/package.json index cf4e4f3222..ae00c94618 100644 --- a/contracts/asset-proxy/package.json +++ b/contracts/asset-proxy/package.json @@ -38,7 +38,7 @@ "docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES" }, "config": { - "abis": "./test/generated-artifacts/@(BalancerBridge|BancorBridge|ChaiBridge|CurveBridge|DexForwarderBridge|DydxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IBalancerPool|IBancorNetwork|IChai|ICurve|IDydx|IDydxBridge|IERC20Bridge|IEth2Dai|IGasToken|IKyberNetworkProxy|IMStable|IMooniswap|IUniswapExchange|IUniswapExchangeFactory|IUniswapV2Router01|KyberBridge|MStableBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MixinGasToken|MooniswapBridge|MultiAssetProxy|Ownable|StaticCallProxy|SushiSwapBridge|TestBancorBridge|TestChaiBridge|TestDexForwarderBridge|TestDydxBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|TestUniswapV2Bridge|UniswapBridge|UniswapV2Bridge).json", + "abis": "./test/generated-artifacts/@(BalancerBridge|BancorBridge|ChaiBridge|CreamBridge|CurveBridge|DexForwarderBridge|DydxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IBalancerPool|IBancorNetwork|IChai|ICurve|IDydx|IDydxBridge|IERC20Bridge|IEth2Dai|IGasToken|IKyberNetworkProxy|IMStable|IMooniswap|IUniswapExchange|IUniswapExchangeFactory|IUniswapV2Router01|KyberBridge|MStableBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MixinGasToken|MooniswapBridge|MultiAssetProxy|Ownable|StaticCallProxy|SushiSwapBridge|TestBancorBridge|TestChaiBridge|TestDexForwarderBridge|TestDydxBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|TestUniswapV2Bridge|UniswapBridge|UniswapV2Bridge).json", "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually." }, "repository": { diff --git a/contracts/asset-proxy/src/artifacts.ts b/contracts/asset-proxy/src/artifacts.ts index 5385d5d000..57e37ce8ff 100644 --- a/contracts/asset-proxy/src/artifacts.ts +++ b/contracts/asset-proxy/src/artifacts.ts @@ -8,6 +8,7 @@ import { ContractArtifact } from 'ethereum-types'; import * as BalancerBridge from '../generated-artifacts/BalancerBridge.json'; import * as BancorBridge from '../generated-artifacts/BancorBridge.json'; import * as ChaiBridge from '../generated-artifacts/ChaiBridge.json'; +import * as CreamBridge from '../generated-artifacts/CreamBridge.json'; import * as CurveBridge from '../generated-artifacts/CurveBridge.json'; import * as DexForwarderBridge from '../generated-artifacts/DexForwarderBridge.json'; import * as DydxBridge from '../generated-artifacts/DydxBridge.json'; @@ -70,6 +71,7 @@ export const artifacts = { BalancerBridge: BalancerBridge as ContractArtifact, BancorBridge: BancorBridge as ContractArtifact, ChaiBridge: ChaiBridge as ContractArtifact, + CreamBridge: CreamBridge as ContractArtifact, CurveBridge: CurveBridge as ContractArtifact, DexForwarderBridge: DexForwarderBridge as ContractArtifact, DydxBridge: DydxBridge as ContractArtifact, diff --git a/contracts/asset-proxy/src/wrappers.ts b/contracts/asset-proxy/src/wrappers.ts index 8107eaf766..f9220bab2d 100644 --- a/contracts/asset-proxy/src/wrappers.ts +++ b/contracts/asset-proxy/src/wrappers.ts @@ -6,6 +6,7 @@ export * from '../generated-wrappers/balancer_bridge'; export * from '../generated-wrappers/bancor_bridge'; export * from '../generated-wrappers/chai_bridge'; +export * from '../generated-wrappers/cream_bridge'; export * from '../generated-wrappers/curve_bridge'; export * from '../generated-wrappers/dex_forwarder_bridge'; export * from '../generated-wrappers/dydx_bridge'; diff --git a/contracts/asset-proxy/test/artifacts.ts b/contracts/asset-proxy/test/artifacts.ts index aa01f1dc52..85c941cd6f 100644 --- a/contracts/asset-proxy/test/artifacts.ts +++ b/contracts/asset-proxy/test/artifacts.ts @@ -8,6 +8,7 @@ import { ContractArtifact } from 'ethereum-types'; import * as BalancerBridge from '../test/generated-artifacts/BalancerBridge.json'; import * as BancorBridge from '../test/generated-artifacts/BancorBridge.json'; import * as ChaiBridge from '../test/generated-artifacts/ChaiBridge.json'; +import * as CreamBridge from '../test/generated-artifacts/CreamBridge.json'; import * as CurveBridge from '../test/generated-artifacts/CurveBridge.json'; import * as DexForwarderBridge from '../test/generated-artifacts/DexForwarderBridge.json'; import * as DydxBridge from '../test/generated-artifacts/DydxBridge.json'; @@ -70,6 +71,7 @@ export const artifacts = { BalancerBridge: BalancerBridge as ContractArtifact, BancorBridge: BancorBridge as ContractArtifact, ChaiBridge: ChaiBridge as ContractArtifact, + CreamBridge: CreamBridge as ContractArtifact, CurveBridge: CurveBridge as ContractArtifact, DexForwarderBridge: DexForwarderBridge as ContractArtifact, DydxBridge: DydxBridge as ContractArtifact, diff --git a/contracts/asset-proxy/test/wrappers.ts b/contracts/asset-proxy/test/wrappers.ts index 4ae6089533..bf2954ea01 100644 --- a/contracts/asset-proxy/test/wrappers.ts +++ b/contracts/asset-proxy/test/wrappers.ts @@ -6,6 +6,7 @@ export * from '../test/generated-wrappers/balancer_bridge'; export * from '../test/generated-wrappers/bancor_bridge'; export * from '../test/generated-wrappers/chai_bridge'; +export * from '../test/generated-wrappers/cream_bridge'; export * from '../test/generated-wrappers/curve_bridge'; export * from '../test/generated-wrappers/dex_forwarder_bridge'; export * from '../test/generated-wrappers/dydx_bridge'; diff --git a/contracts/asset-proxy/tsconfig.json b/contracts/asset-proxy/tsconfig.json index ccb4c12320..2e7053bee1 100644 --- a/contracts/asset-proxy/tsconfig.json +++ b/contracts/asset-proxy/tsconfig.json @@ -6,6 +6,7 @@ "generated-artifacts/BalancerBridge.json", "generated-artifacts/BancorBridge.json", "generated-artifacts/ChaiBridge.json", + "generated-artifacts/CreamBridge.json", "generated-artifacts/CurveBridge.json", "generated-artifacts/DexForwarderBridge.json", "generated-artifacts/DydxBridge.json", @@ -58,6 +59,7 @@ "test/generated-artifacts/BalancerBridge.json", "test/generated-artifacts/BancorBridge.json", "test/generated-artifacts/ChaiBridge.json", + "test/generated-artifacts/CreamBridge.json", "test/generated-artifacts/CurveBridge.json", "test/generated-artifacts/DexForwarderBridge.json", "test/generated-artifacts/DydxBridge.json",