mess with the gas estimation code a bit to allow swapping

This commit is contained in:
Moody Salem 2021-04-28 18:58:53 -05:00
parent 5b49cedebb
commit b09eb8fb52
No known key found for this signature in database
GPG Key ID: 8CB5CD10385138DB

@ -28,18 +28,20 @@ interface SwapCall {
value: string
}
interface SuccessfulCall {
interface SwapCallEstimate {
call: SwapCall
}
interface SuccessfulCall extends SwapCallEstimate {
call: SwapCall
gasEstimate: BigNumber
}
interface FailedCall {
interface FailedCall extends SwapCallEstimate {
call: SwapCall
error: Error
}
type EstimatedSwapCall = SuccessfulCall | FailedCall
/**
* Returns the swap calls that can be used to make the trade
* @param trade trade to execute
@ -141,7 +143,7 @@ export function useSwapCallback(
return {
state: SwapCallbackState.VALID,
callback: async function onSwap(): Promise<string> {
const estimatedCalls: EstimatedSwapCall[] = await Promise.all(
const estimatedCalls: SwapCallEstimate[] = await Promise.all(
swapCalls.map((call) => {
const { address, calldata, value } = call
@ -175,13 +177,24 @@ export function useSwapCallback(
console.debug('Call threw error', call, callError)
let errorMessage: string
switch (callError.reason) {
case 'UniswapV2Router: EXPIRED':
errorMessage =
'The transaction could not be sent because the deadline has passed. Please check that your transaction deadline is not too low.'
break
case 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT':
case 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT':
errorMessage =
'This transaction will not succeed either due to price movement or fee on transfer. Try increasing your slippage tolerance.'
break
case 'UniswapV2: TRANSFER_FAILED':
errorMessage = 'The token could not be transferred. There may be an issue with the token.'
break
case 'UniswapV2: K':
errorMessage =
'The Uniswap invariant x*y=k was not satisfied by the swap. This usually means one of the tokens you are swapping incorporates custom behavior on transfer.'
break
default:
errorMessage = `The transaction cannot succeed due to error: ${callError.reason}. This is probably an issue with one of the tokens you are swapping.`
return { call }
}
return { call, error: new Error(errorMessage) }
})
@ -190,21 +203,25 @@ export function useSwapCallback(
)
// a successful estimation is a bignumber gas estimate and the next call is also a bignumber gas estimate
const successfulEstimation = estimatedCalls.find(
let bestCallOption: SuccessfulCall | SwapCallEstimate | undefined = estimatedCalls.find(
(el, ix, list): el is SuccessfulCall =>
'gasEstimate' in el && (ix === list.length - 1 || 'gasEstimate' in list[ix + 1])
)
if (!successfulEstimation) {
// check if any calls errored with a recognizable error
if (!bestCallOption) {
const errorCalls = estimatedCalls.filter((call): call is FailedCall => 'error' in call)
if (errorCalls.length > 0) throw errorCalls[errorCalls.length - 1].error
throw new Error('Unexpected error. Please contact support.')
const firstNoErrorCall = estimatedCalls.find<SwapCallEstimate>(
(call): call is SwapCallEstimate => !('error' in call)
)
if (!firstNoErrorCall) throw new Error('Unexpected error. Could not estimate gas for the swap.')
bestCallOption = firstNoErrorCall
}
const {
call: { address, calldata, value },
gasEstimate,
} = successfulEstimation
} = bestCallOption
return library
.getSigner()
@ -212,7 +229,10 @@ export function useSwapCallback(
from: account,
to: address,
data: calldata,
gasLimit: calculateGasMargin(gasEstimate),
// let the wallet try if we can't estimate the gas
...('gasEstimate' in bestCallOption
? { gasLimit: calculateGasMargin(bestCallOption.gasEstimate) }
: { gasLimit: 1_000_000 }),
...(value && !isZero(value) ? { value } : {}),
})
.then((response) => {