diff --git a/app/assets/v2/js/cart.js b/app/assets/v2/js/cart.js index 8071f5fe972..adc07492285 100644 --- a/app/assets/v2/js/cart.js +++ b/app/assets/v2/js/cart.js @@ -199,12 +199,30 @@ Vue.component('grants-cart', { // Estimated gas limit for the transaction donationInputsGasLimit() { - // Based on contract tests, we use the heuristic below to get gas estimate. This is done - // instead of `estimateGas()` so we can send the donation transaction before the approval txs - // are confirmed, because if the approval txs are not confirmed then estimateGas will fail. - // The estimates used here are based on single donations (i.e. one item in the cart). Because - // gas prices go down with batched transactions, whereas this assumes they're constant, - // this gives us a conservative estimate + // The below heuristics are used instead of `estimateGas()` so we can send the donation + // transaction before the approval txs are confirmed, because if the approval txs + // are not confirmed then estimateGas will fail. + + // If we have a cart where all donations are in Dai, we use a linear regression to + // estimate gas costs based on real checkout transaction data, and add a 50% margin + const donationCurrencies = this.donationInputs.map(donation => donation.token); + const isAllDai = donationCurrencies.every((addr, index, array) => addr === array[0]); + + if (isAllDai) { + if (donationCurrencies.length === 1) { + // Special case since we overestimate here otherwise + return 80000; + } + // Below curve found by running script at the repo below around 4PM PT on 2020-Jun-17 + // then generating a conservative best-fit line + // https://github.com/mds1/Gitcoin-Checkout-Gas-Analysis + return 1.3 * (27000 * donationCurrencies.length + 75000); + } + + // Otherwise, based on contract tests, we use the more conservative heuristic below to get + // a gas estimate. The estimates used here are based on testing the cost of a single + // donation (i.e. one item in the cart). Because gas prices go down with batched + // transactions, whereas this assumes they're constant, this gives us a conservative estimate const gasLimit = this.donationInputs.reduce((accumulator, currentValue) => { return currentValue.token === ETH_ADDRESS ? accumulator + 50000// ETH donation gas estimate