Skip to content
This repository has been archived by the owner on Oct 15, 2024. It is now read-only.

Commit

Permalink
fix: Provide default gas estimate for validation calls
Browse files Browse the repository at this point in the history
  • Loading branch information
dekz committed Jun 17, 2020
1 parent 18356b9 commit 0489051
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 11 deletions.
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const DEFAULT_LOGGER_INCLUDE_TIMESTAMP = true;
export const ONE_SECOND_MS = 1000;
export const ONE_MINUTE_MS = ONE_SECOND_MS * 60;
export const TEN_MINUTES_MS = ONE_MINUTE_MS * 10;
export const DEFAULT_VALIDATION_GAS_LIMIT = 10e6;

// The number of orders to post to Mesh at one time
export const MESH_ORDERS_BATCH_SIZE = 200;
Expand Down
3 changes: 2 additions & 1 deletion src/services/meta_transaction_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
RFQT_SKIP_BUY_REQUESTS,
} from '../config';
import {
DEFAULT_VALIDATION_GAS_LIMIT,
ONE_GWEI,
ONE_MINUTE_MS,
ONE_SECOND_MS,
Expand Down Expand Up @@ -265,6 +266,7 @@ export class MetaTransactionService {
from: PUBLIC_ADDRESS_FOR_ETH_CALLS,
gasPrice,
value: protocolFee,
gas: DEFAULT_VALIDATION_GAS_LIMIT,
});
} catch (err) {
// we reach into the underlying revert and throw it instead of
Expand Down Expand Up @@ -296,7 +298,6 @@ export class MetaTransactionService {
protocolFee: BigNumber,
): Promise<PartialTxParams> {
const gasPrice = zeroExTransaction.gasPrice;
// TODO(dekz): our pattern is to eth_call and estimateGas in parallel and return the result of eth_call validations
const gas = await this._contractWrappers.exchange
.executeTransaction(zeroExTransaction, signature)
.estimateGasAsync({
Expand Down
32 changes: 22 additions & 10 deletions src/services/swap_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
RFQT_SKIP_BUY_REQUESTS,
} from '../config';
import {
DEFAULT_VALIDATION_GAS_LIMIT,
GAS_LIMIT_BUFFER_MULTIPLIER,
GST2_WALLET_ADDRESSES,
ONE,
Expand Down Expand Up @@ -142,7 +143,10 @@ export class SwapService {
// Add a buffer to get the worst case gas estimate
const worstCaseGasEstimate = conservativeBestCaseGasEstimate.times(GAS_LIMIT_BUFFER_MULTIPLIER).integerValue();
// Cap the refund at 50% our best estimate
const estimatedGasTokenRefund = BigNumber.min(conservativeBestCaseGasEstimate.div(2), gasTokenRefund);
const estimatedGasTokenRefund = BigNumber.min(
conservativeBestCaseGasEstimate.div(2),
gasTokenRefund,
).decimalPlaces(0);
const { price, guaranteedPrice } = await this._getSwapQuotePriceAsync(
buyAmount,
buyTokenAddress,
Expand Down Expand Up @@ -282,12 +286,8 @@ export class SwapService {
}

private async _estimateGasOrThrowRevertErrorAsync(txData: Partial<TxData>): Promise<BigNumber> {
// Perform this concurrently
// if the call fails the gas estimation will also fail, we can throw a more helpful
// error message than gas estimation failure
const estimateGasPromise = this._web3Wrapper.estimateGasAsync(txData).catch(_e => 0);
await this._throwIfCallIsRevertErrorAsync(txData);
const gas = await estimateGasPromise;
const gas = await this._web3Wrapper.estimateGasAsync(txData).catch(_e => DEFAULT_VALIDATION_GAS_LIMIT);
await this._throwIfCallIsRevertErrorAsync({ ...txData, gas });
return new BigNumber(gas);
}

Expand All @@ -298,9 +298,21 @@ export class SwapService {
callResult = await this._web3Wrapper.callAsync(txData);
} catch (e) {
// RPCSubprovider can throw if .error exists on the response payload
// This `error` response occurs from Parity nodes (incl Alchemy) but not on INFURA (geth)
revertError = decodeThrownErrorAsRevertError(e);
throw revertError;
// This `error` response occurs from Parity nodes (incl Alchemy) and Geth nodes >= 1.9.14
// Geth 1.9.15
if (e.message && /execution reverted/.test(e.message) && e.data) {
try {
revertError = RevertError.decode(e.data, false);
} catch (e) {
// No revert error
}
} else {
revertError = decodeThrownErrorAsRevertError(e);
throw revertError;
}
if (revertError) {
throw revertError;
}
}
try {
revertError = RevertError.decode(callResult, false);
Expand Down

0 comments on commit 0489051

Please sign in to comment.