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/LibOrder.sol";
import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol"; import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol";
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
import "@0x/contracts-utils/contracts/src/LibBytes.sol";
import "./IDevUtils.sol"; import "./IDevUtils.sol";
import "./IERC20BridgeSampler.sol"; import "./IERC20BridgeSampler.sol";
import "./IEth2Dai.sol"; import "./IEth2Dai.sol";
@@ -442,7 +443,7 @@ contract ERC20BridgeSampler is
/// @param takerTokenAmounts Taker token sell amount for each sample. /// @param takerTokenAmounts Taker token sell amount for each sample.
/// @return makerTokenAmounts Maker amounts bought at each taker token /// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount. /// amount.
function sampleSellsFromLiquidityProvider( function sampleSellsFromLiquidityProviderRegistry(
address registryAddress, address registryAddress,
address takerToken, address takerToken,
address makerToken, address makerToken,
@@ -452,14 +453,21 @@ contract ERC20BridgeSampler is
view view
returns (uint256[] memory makerTokenAmounts) 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( address providerAddress = getLiquidityProviderFromRegistry(
registryAddress, registryAddress,
takerToken, takerToken,
makerToken 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++) { for (uint256 i = 0; i < numSamples; i++) {
(bool didSucceed, bytes memory resultData) = (bool didSucceed, bytes memory resultData) =
providerAddress.staticcall.gas(DEFAULT_CALL_GAS)( providerAddress.staticcall.gas(DEFAULT_CALL_GAS)(
@@ -487,7 +495,7 @@ contract ERC20BridgeSampler is
/// @param makerTokenAmounts Maker token buy amount for each sample. /// @param makerTokenAmounts Maker token buy amount for each sample.
/// @return takerTokenAmounts Taker amounts sold at each maker token /// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount. /// amount.
function sampleBuysFromLiquidityProvider( function sampleBuysFromLiquidityProviderRegistry(
address registryAddress, address registryAddress,
address takerToken, address takerToken,
address makerToken, address makerToken,
@@ -497,14 +505,22 @@ contract ERC20BridgeSampler is
view view
returns (uint256[] memory takerTokenAmounts) 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( address providerAddress = getLiquidityProviderFromRegistry(
registryAddress, registryAddress,
takerToken, takerToken,
makerToken makerToken
); );
// If provider doesn't exist, return all zeros.
if (providerAddress == address(0)) {
return takerTokenAmounts;
}
uint256 numSamples = makerTokenAmounts.length; // Otherwise, query liquidity provider for quotes.
takerTokenAmounts = new uint256[](numSamples);
for (uint256 i = 0; i < numSamples; i++) { for (uint256 i = 0; i < numSamples; i++) {
(bool didSucceed, bytes memory resultData) = (bool didSucceed, bytes memory resultData) =
providerAddress.staticcall.gas(DEFAULT_CALL_GAS)( 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 /// @dev Returns the address of a liquidity provider for the given market
/// (takerToken, makerToken), from a registry of liquidity providers. /// (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 takerToken Taker asset managed by liquidity provider.
/// @param makerToken Maker 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( function getLiquidityProviderFromRegistry(
address registryAddress, address registryAddress,
address takerToken, address takerToken,
@@ -537,12 +554,17 @@ contract ERC20BridgeSampler is
) )
public public
view view
returns (address) returns (address providerAddress)
{ {
return ILiquidityProviderRegistry(registryAddress).getLiquidityProviderForMarket( bytes memory callData = abi.encodeWithSelector(
ILiquidityProviderRegistry(0).getLiquidityProviderForMarket.selector,
takerToken, takerToken,
makerToken makerToken
); );
(bool didSucceed, bytes memory returnData) = registryAddress.staticcall(callData);
if (didSucceed) {
return LibBytes.readAddress(returnData, 0);
}
} }
/// @dev Overridable way to get token decimals. /// @dev Overridable way to get token decimals.

View File

@@ -151,14 +151,14 @@ interface IERC20BridgeSampler {
returns (uint256[] memory makerTokenAmounts); returns (uint256[] memory makerTokenAmounts);
/// @dev Sample sell quotes from an arbitrary on-chain liquidity provider. /// @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 takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy). /// @param makerToken Address of the maker token (what to buy).
/// @param takerTokenAmounts Taker token sell amount for each sample. /// @param takerTokenAmounts Taker token sell amount for each sample.
/// @return makerTokenAmounts Maker amounts bought at each taker token /// @return makerTokenAmounts Maker amounts bought at each taker token
/// amount. /// amount.
function sampleSellsFromLiquidityProvider( function sampleSellsFromLiquidityProviderRegistry(
address providerAddress, address registryAddress,
address takerToken, address takerToken,
address makerToken, address makerToken,
uint256[] calldata takerTokenAmounts uint256[] calldata takerTokenAmounts
@@ -168,14 +168,14 @@ interface IERC20BridgeSampler {
returns (uint256[] memory makerTokenAmounts); returns (uint256[] memory makerTokenAmounts);
/// @dev Sample buy quotes from an arbitrary on-chain liquidity provider. /// @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 takerToken Address of the taker token (what to sell).
/// @param makerToken Address of the maker token (what to buy). /// @param makerToken Address of the maker token (what to buy).
/// @param makerTokenAmounts Maker token buy amount for each sample. /// @param makerTokenAmounts Maker token buy amount for each sample.
/// @return takerTokenAmounts Taker amounts sold at each maker token /// @return takerTokenAmounts Taker amounts sold at each maker token
/// amount. /// amount.
function sampleBuysFromLiquidityProvider( function sampleBuysFromLiquidityProviderRegistry(
address providerAddress, address registryAddress,
address takerToken, address takerToken,
address makerToken, address makerToken,
uint256[] calldata makerTokenAmounts uint256[] calldata makerTokenAmounts
@@ -183,4 +183,19 @@ interface IERC20BridgeSampler {
external external
view view
returns (uint256[] memory takerTokenAmounts); 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 ERC20BridgeSampler from '../generated-artifacts/ERC20BridgeSampler.json';
import * as IERC20BridgeSampler from '../generated-artifacts/IERC20BridgeSampler.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 = { export const artifacts = {
ERC20BridgeSampler: ERC20BridgeSampler as ContractArtifact, ERC20BridgeSampler: ERC20BridgeSampler as ContractArtifact,
IERC20BridgeSampler: IERC20BridgeSampler 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/erc20_bridge_sampler';
export * from '../generated-wrappers/i_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": [ "files": [
"generated-artifacts/ERC20BridgeSampler.json", "generated-artifacts/ERC20BridgeSampler.json",
"generated-artifacts/IERC20BridgeSampler.json", "generated-artifacts/IERC20BridgeSampler.json",
"generated-artifacts/ILiquidityProvider.json",
"generated-artifacts/ILiquidityProviderRegistry.json",
"test/generated-artifacts/ERC20BridgeSampler.json", "test/generated-artifacts/ERC20BridgeSampler.json",
"test/generated-artifacts/ICurve.json", "test/generated-artifacts/ICurve.json",
"test/generated-artifacts/IDevUtils.json", "test/generated-artifacts/IDevUtils.json",