diff --git a/contracts/erc20-bridge-sampler/CHANGELOG.json b/contracts/erc20-bridge-sampler/CHANGELOG.json index dd976b0b37..cb716c3d75 100644 --- a/contracts/erc20-bridge-sampler/CHANGELOG.json +++ b/contracts/erc20-bridge-sampler/CHANGELOG.json @@ -5,6 +5,10 @@ { "note": "Add generic liquidity provider sampling", "pr": 2487 + }, + { + "note": "Use liquidity provider registry in sampler", + "pr": 2499 } ] }, diff --git a/contracts/erc20-bridge-sampler/contracts/src/ERC20BridgeSampler.sol b/contracts/erc20-bridge-sampler/contracts/src/ERC20BridgeSampler.sol index 559d3f3c63..6eb1d318d5 100644 --- a/contracts/erc20-bridge-sampler/contracts/src/ERC20BridgeSampler.sol +++ b/contracts/erc20-bridge-sampler/contracts/src/ERC20BridgeSampler.sol @@ -24,6 +24,7 @@ import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol"; import "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol"; import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol"; import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; +import "@0x/contracts-utils/contracts/src/LibBytes.sol"; import "./IDevUtils.sol"; import "./IERC20BridgeSampler.sol"; import "./IEth2Dai.sol"; @@ -31,6 +32,7 @@ import "./IKyberNetwork.sol"; import "./IUniswapExchangeQuotes.sol"; import "./ICurve.sol"; import "./ILiquidityProvider.sol"; +import "./ILiquidityProviderRegistry.sol"; contract ERC20BridgeSampler is @@ -435,14 +437,14 @@ contract ERC20BridgeSampler is } /// @dev Sample sell quotes from an arbitrary on-chain liquidity provider. - /// @param providerAddress Address of the liquidity provider contract. + /// @param registryAddress Address of the liquidity provider registry contract. /// @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. /// @return makerTokenAmounts Maker amounts bought at each taker token /// amount. - function sampleSellsFromLiquidityProvider( - address providerAddress, + function sampleSellsFromLiquidityProviderRegistry( + address registryAddress, address takerToken, address makerToken, uint256[] memory takerTokenAmounts @@ -451,8 +453,21 @@ contract ERC20BridgeSampler is view returns (uint256[] memory makerTokenAmounts) { + // Initialize array of maker token amounts. uint256 numSamples = takerTokenAmounts.length; makerTokenAmounts = new uint256[](numSamples); + + // Query registry for provider address. + address providerAddress = getLiquidityProviderFromRegistry( + registryAddress, + takerToken, + makerToken + ); + // If provider doesn't exist, return all zeros. + if (providerAddress == address(0)) { + return makerTokenAmounts; + } + for (uint256 i = 0; i < numSamples; i++) { (bool didSucceed, bytes memory resultData) = providerAddress.staticcall.gas(DEFAULT_CALL_GAS)( @@ -474,14 +489,14 @@ contract ERC20BridgeSampler is } /// @dev Sample buy quotes from an arbitrary on-chain liquidity provider. - /// @param providerAddress Address of the liquidity provider contract. + /// @param registryAddress Address of the liquidity provider registry contract. /// @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 takerTokenAmounts Taker amounts sold at each maker token /// amount. - function sampleBuysFromLiquidityProvider( - address providerAddress, + function sampleBuysFromLiquidityProviderRegistry( + address registryAddress, address takerToken, address makerToken, uint256[] memory makerTokenAmounts @@ -490,8 +505,22 @@ contract ERC20BridgeSampler is view returns (uint256[] memory takerTokenAmounts) { + // Initialize array of taker token amounts. uint256 numSamples = makerTokenAmounts.length; takerTokenAmounts = new uint256[](numSamples); + + // Query registry for provider address. + address providerAddress = getLiquidityProviderFromRegistry( + registryAddress, + takerToken, + makerToken + ); + // If provider doesn't exist, return all zeros. + if (providerAddress == address(0)) { + return takerTokenAmounts; + } + + // Otherwise, query liquidity provider for quotes. for (uint256 i = 0; i < numSamples; i++) { (bool didSucceed, bytes memory resultData) = providerAddress.staticcall.gas(DEFAULT_CALL_GAS)( @@ -512,6 +541,32 @@ contract ERC20BridgeSampler is } } + /// @dev Returns the address of a liquidity provider for the given market + /// (takerToken, makerToken), from a registry of liquidity providers. + /// Returns address(0) if no such provider exists in the registry. + /// @param takerToken Taker asset managed by liquidity provider. + /// @param makerToken Maker asset managed by liquidity provider. + /// @return providerAddress Address of the liquidity provider. + function getLiquidityProviderFromRegistry( + address registryAddress, + address takerToken, + address makerToken + ) + public + view + returns (address providerAddress) + { + bytes memory callData = abi.encodeWithSelector( + ILiquidityProviderRegistry(0).getLiquidityProviderForMarket.selector, + takerToken, + makerToken + ); + (bool didSucceed, bytes memory returnData) = registryAddress.staticcall(callData); + if (didSucceed) { + return LibBytes.readAddress(returnData, 0); + } + } + /// @dev Overridable way to get token decimals. /// @param tokenAddress Address of the token. /// @return decimals The decimal places for the token. diff --git a/contracts/erc20-bridge-sampler/contracts/src/IERC20BridgeSampler.sol b/contracts/erc20-bridge-sampler/contracts/src/IERC20BridgeSampler.sol index 7c12da6260..bdc0cb78a9 100644 --- a/contracts/erc20-bridge-sampler/contracts/src/IERC20BridgeSampler.sol +++ b/contracts/erc20-bridge-sampler/contracts/src/IERC20BridgeSampler.sol @@ -151,14 +151,14 @@ interface IERC20BridgeSampler { returns (uint256[] memory makerTokenAmounts); /// @dev Sample sell quotes from an arbitrary on-chain liquidity provider. - /// @param providerAddress Address of the liquidity provider contract. + /// @param registryAddress Address of the liquidity provider registry contract. /// @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. /// @return makerTokenAmounts Maker amounts bought at each taker token /// amount. - function sampleSellsFromLiquidityProvider( - address providerAddress, + function sampleSellsFromLiquidityProviderRegistry( + address registryAddress, address takerToken, address makerToken, uint256[] calldata takerTokenAmounts @@ -168,14 +168,14 @@ interface IERC20BridgeSampler { returns (uint256[] memory makerTokenAmounts); /// @dev Sample buy quotes from an arbitrary on-chain liquidity provider. - /// @param providerAddress Address of the liquidity provider contract. + /// @param registryAddress Address of the liquidity provider registry contract. /// @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 takerTokenAmounts Taker amounts sold at each maker token /// amount. - function sampleBuysFromLiquidityProvider( - address providerAddress, + function sampleBuysFromLiquidityProviderRegistry( + address registryAddress, address takerToken, address makerToken, uint256[] calldata makerTokenAmounts @@ -183,4 +183,19 @@ interface IERC20BridgeSampler { external view returns (uint256[] memory takerTokenAmounts); + + /// @dev Returns the address of a liquidity provider for the given market + /// (takerToken, makerToken), from a registry of liquidity providers. + /// Returns address(0) if no such provider exists in the registry. + /// @param takerToken Taker asset managed by liquidity provider. + /// @param makerToken Maker asset managed by liquidity provider. + /// @return providerAddress Address of the liquidity provider. + function getLiquidityProviderFromRegistry( + address registryAddress, + address takerToken, + address makerToken + ) + external + view + returns (address providerAddress); } diff --git a/contracts/erc20-bridge-sampler/contracts/src/ILiquidityProviderRegistry.sol b/contracts/erc20-bridge-sampler/contracts/src/ILiquidityProviderRegistry.sol new file mode 100644 index 0000000000..22a39299b1 --- /dev/null +++ b/contracts/erc20-bridge-sampler/contracts/src/ILiquidityProviderRegistry.sol @@ -0,0 +1,36 @@ +/* + + Copyright 2019 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; + + +interface ILiquidityProviderRegistry { + + /// @dev Returns the address of a liquidity provider for the given market + /// (takerToken, makerToken), reverting if the pool does not exist. + /// @param takerToken Taker asset managed by liquidity provider. + /// @param makerToken Maker asset managed by liquidity provider. + /// @return Address of the liquidity provider. + function getLiquidityProviderForMarket( + address takerToken, + address makerToken + ) + external + view + returns (address providerAddress); +} diff --git a/contracts/erc20-bridge-sampler/package.json b/contracts/erc20-bridge-sampler/package.json index 46906d6519..1a348974ae 100644 --- a/contracts/erc20-bridge-sampler/package.json +++ b/contracts/erc20-bridge-sampler/package.json @@ -36,9 +36,9 @@ "compile:truffle": "truffle compile" }, "config": { - "publicInterfaceContracts": "ERC20BridgeSampler,IERC20BridgeSampler", + "publicInterfaceContracts": "ERC20BridgeSampler,IERC20BridgeSampler,ILiquidityProvider,ILiquidityProviderRegistry", "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.", - "abis": "./test/generated-artifacts/@(ERC20BridgeSampler|ICurve|IDevUtils|IERC20BridgeSampler|IEth2Dai|IKyberNetwork|ILiquidityProvider|IUniswapExchangeQuotes|TestERC20BridgeSampler).json" + "abis": "./test/generated-artifacts/@(ERC20BridgeSampler|ICurve|IDevUtils|IERC20BridgeSampler|IEth2Dai|IKyberNetwork|ILiquidityProvider|ILiquidityProviderRegistry|IUniswapExchangeQuotes|TestERC20BridgeSampler).json" }, "repository": { "type": "git", diff --git a/contracts/erc20-bridge-sampler/src/artifacts.ts b/contracts/erc20-bridge-sampler/src/artifacts.ts index 41366d2e0e..1f15319fd0 100644 --- a/contracts/erc20-bridge-sampler/src/artifacts.ts +++ b/contracts/erc20-bridge-sampler/src/artifacts.ts @@ -7,7 +7,11 @@ import { ContractArtifact } from 'ethereum-types'; import * as ERC20BridgeSampler from '../generated-artifacts/ERC20BridgeSampler.json'; import * as IERC20BridgeSampler from '../generated-artifacts/IERC20BridgeSampler.json'; +import * as ILiquidityProvider from '../generated-artifacts/ILiquidityProvider.json'; +import * as ILiquidityProviderRegistry from '../generated-artifacts/ILiquidityProviderRegistry.json'; export const artifacts = { ERC20BridgeSampler: ERC20BridgeSampler as ContractArtifact, IERC20BridgeSampler: IERC20BridgeSampler as ContractArtifact, + ILiquidityProvider: ILiquidityProvider as ContractArtifact, + ILiquidityProviderRegistry: ILiquidityProviderRegistry as ContractArtifact, }; diff --git a/contracts/erc20-bridge-sampler/src/wrappers.ts b/contracts/erc20-bridge-sampler/src/wrappers.ts index d1921d6176..968f08623c 100644 --- a/contracts/erc20-bridge-sampler/src/wrappers.ts +++ b/contracts/erc20-bridge-sampler/src/wrappers.ts @@ -5,3 +5,5 @@ */ export * from '../generated-wrappers/erc20_bridge_sampler'; export * from '../generated-wrappers/i_erc20_bridge_sampler'; +export * from '../generated-wrappers/i_liquidity_provider'; +export * from '../generated-wrappers/i_liquidity_provider_registry'; diff --git a/contracts/erc20-bridge-sampler/test/artifacts.ts b/contracts/erc20-bridge-sampler/test/artifacts.ts index 6e9a15445c..2ed14d12a6 100644 --- a/contracts/erc20-bridge-sampler/test/artifacts.ts +++ b/contracts/erc20-bridge-sampler/test/artifacts.ts @@ -12,6 +12,7 @@ import * as IERC20BridgeSampler from '../test/generated-artifacts/IERC20BridgeSa import * as IEth2Dai from '../test/generated-artifacts/IEth2Dai.json'; import * as IKyberNetwork from '../test/generated-artifacts/IKyberNetwork.json'; import * as ILiquidityProvider from '../test/generated-artifacts/ILiquidityProvider.json'; +import * as ILiquidityProviderRegistry from '../test/generated-artifacts/ILiquidityProviderRegistry.json'; import * as IUniswapExchangeQuotes from '../test/generated-artifacts/IUniswapExchangeQuotes.json'; import * as TestERC20BridgeSampler from '../test/generated-artifacts/TestERC20BridgeSampler.json'; export const artifacts = { @@ -22,6 +23,7 @@ export const artifacts = { IEth2Dai: IEth2Dai as ContractArtifact, IKyberNetwork: IKyberNetwork as ContractArtifact, ILiquidityProvider: ILiquidityProvider as ContractArtifact, + ILiquidityProviderRegistry: ILiquidityProviderRegistry as ContractArtifact, IUniswapExchangeQuotes: IUniswapExchangeQuotes as ContractArtifact, TestERC20BridgeSampler: TestERC20BridgeSampler as ContractArtifact, }; diff --git a/contracts/erc20-bridge-sampler/test/wrappers.ts b/contracts/erc20-bridge-sampler/test/wrappers.ts index 55db751e47..4465c09dfd 100644 --- a/contracts/erc20-bridge-sampler/test/wrappers.ts +++ b/contracts/erc20-bridge-sampler/test/wrappers.ts @@ -10,5 +10,6 @@ export * from '../test/generated-wrappers/i_erc20_bridge_sampler'; export * from '../test/generated-wrappers/i_eth2_dai'; export * from '../test/generated-wrappers/i_kyber_network'; export * from '../test/generated-wrappers/i_liquidity_provider'; +export * from '../test/generated-wrappers/i_liquidity_provider_registry'; export * from '../test/generated-wrappers/i_uniswap_exchange_quotes'; export * from '../test/generated-wrappers/test_erc20_bridge_sampler'; diff --git a/contracts/erc20-bridge-sampler/tsconfig.json b/contracts/erc20-bridge-sampler/tsconfig.json index a8cc5145ea..c8e6f55115 100644 --- a/contracts/erc20-bridge-sampler/tsconfig.json +++ b/contracts/erc20-bridge-sampler/tsconfig.json @@ -5,6 +5,8 @@ "files": [ "generated-artifacts/ERC20BridgeSampler.json", "generated-artifacts/IERC20BridgeSampler.json", + "generated-artifacts/ILiquidityProvider.json", + "generated-artifacts/ILiquidityProviderRegistry.json", "test/generated-artifacts/ERC20BridgeSampler.json", "test/generated-artifacts/ICurve.json", "test/generated-artifacts/IDevUtils.json", @@ -12,6 +14,7 @@ "test/generated-artifacts/IEth2Dai.json", "test/generated-artifacts/IKyberNetwork.json", "test/generated-artifacts/ILiquidityProvider.json", + "test/generated-artifacts/ILiquidityProviderRegistry.json", "test/generated-artifacts/IUniswapExchangeQuotes.json", "test/generated-artifacts/TestERC20BridgeSampler.json" ],