Catch reverts when calling registry

This commit is contained in:
Michael Zhu
2020-02-27 10:33:13 -08:00
parent 817049456c
commit a47c031ad1
5 changed files with 60 additions and 15 deletions

View File

@@ -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";
@@ -442,7 +443,7 @@ contract ERC20BridgeSampler is
/// @param takerTokenAmounts Taker token sell amount for each sample.
/// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount.
function sampleSellsFromLiquidityProvider(
function sampleSellsFromLiquidityProviderRegistry(
address registryAddress,
address takerToken,
address makerToken,
@@ -452,14 +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;
}
uint256 numSamples = takerTokenAmounts.length;
makerTokenAmounts = new uint256[](numSamples);
for (uint256 i = 0; i < numSamples; i++) {
(bool didSucceed, bytes memory resultData) =
providerAddress.staticcall.gas(DEFAULT_CALL_GAS)(
@@ -487,7 +495,7 @@ contract ERC20BridgeSampler is
/// @param makerTokenAmounts Maker token buy amount for each sample.
/// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount.
function sampleBuysFromLiquidityProvider(
function sampleBuysFromLiquidityProviderRegistry(
address registryAddress,
address takerToken,
address makerToken,
@@ -497,14 +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;
}
uint256 numSamples = makerTokenAmounts.length;
takerTokenAmounts = new uint256[](numSamples);
// Otherwise, query liquidity provider for quotes.
for (uint256 i = 0; i < numSamples; i++) {
(bool didSucceed, bytes memory resultData) =
providerAddress.staticcall.gas(DEFAULT_CALL_GAS)(
@@ -527,9 +543,10 @@ 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 Address of the liquidity provider.
/// @return providerAddress Address of the liquidity provider.
function getLiquidityProviderFromRegistry(
address registryAddress,
address takerToken,
@@ -537,12 +554,17 @@ contract ERC20BridgeSampler is
)
public
view
returns (address)
returns (address providerAddress)
{
return ILiquidityProviderRegistry(registryAddress).getLiquidityProviderForMarket(
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.

View File

@@ -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);
}

View File

@@ -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,
};

View File

@@ -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';

View File

@@ -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",