From 69eed4addc9974d56ec2b4a0987b61ff7d3af5ab Mon Sep 17 00:00:00 2001 From: "Siyu Jiang (See-You John)" <91580504+jsy1218@users.noreply.github.com> Date: Fri, 13 Dec 2024 09:20:37 -0800 Subject: [PATCH] fix: map virtual swap InsufficientToken as SlippageTooLow (#784) --- src/providers/tenderly-simulation-provider.ts | 4 +++ src/providers/token-provider.ts | 7 +++++ src/util/tenderlySimulationErrorBreakDown.ts | 17 ++++++++++- .../tenderlySimulationErrorBreakDown.test.ts | 28 +++++++++++++------ 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/providers/tenderly-simulation-provider.ts b/src/providers/tenderly-simulation-provider.ts index 238116be2..b2576fe7a 100644 --- a/src/providers/tenderly-simulation-provider.ts +++ b/src/providers/tenderly-simulation-provider.ts @@ -307,6 +307,8 @@ export class TenderlySimulator extends Simulator { ): Promise { const currencyIn = swapRoute.trade.inputAmount.currency; const tokenIn = currencyIn.wrapped; + const currencyOut = swapRoute.trade.outputAmount.currency; + const tokenOut = currencyOut.wrapped; const chainId = this.chainId; if (TENDERLY_NOT_SUPPORTED_CHAINS.includes(chainId)) { @@ -492,6 +494,8 @@ export class TenderlySimulator extends Simulator { return { ...swapRoute, simulationStatus: breakDownTenderlySimulationError( + tokenIn, + tokenOut, (resp.result[2] as JsonRpcError).error.data ), }; diff --git a/src/providers/token-provider.ts b/src/providers/token-provider.ts index 92f8e0dc7..036ee454d 100644 --- a/src/providers/token-provider.ts +++ b/src/providers/token-provider.ts @@ -601,6 +601,13 @@ export const USDC_NATIVE_BASE = new Token( 'USDbC', 'USD Base Coin' ); +export const VIRTUAL_BASE = new Token( + ChainId.BASE, + '0x0b3e328455c4059EEb9e3f84b5543F74E24e7E1b', + 18, + 'VIRTUAL', + 'Virtual Protocol' +); // Base Goerli Tokens export const USDC_BASE_GOERLI = new Token( diff --git a/src/util/tenderlySimulationErrorBreakDown.ts b/src/util/tenderlySimulationErrorBreakDown.ts index 17ce323b2..9eb82a286 100644 --- a/src/util/tenderlySimulationErrorBreakDown.ts +++ b/src/util/tenderlySimulationErrorBreakDown.ts @@ -1,6 +1,9 @@ -import { SimulationStatus } from '../providers'; +import { Token } from '@uniswap/sdk-core'; +import { SimulationStatus, VIRTUAL_BASE } from '../providers'; export function breakDownTenderlySimulationError( + tokenIn: Token, + tokenOut: Token, data?: string ): SimulationStatus { if (data) { @@ -12,6 +15,18 @@ export function breakDownTenderlySimulationError( case '0x08c379a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000025556e697377617056323a20494e53554646494349454e545f4f55545055545f414d4f554e54000000000000000000000000000000000000000000000000000000': // INSUFFICIENT_OUTPUT_AMOUNT case '0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000034949410000000000000000000000000000000000000000000000000000000000': // IIA return SimulationStatus.SlippageTooLow; + case '0x675cae38': // InsufficientToken + if ( + tokenIn.address.toLowerCase() === + VIRTUAL_BASE.address.toLowerCase() || + tokenOut.address.toLowerCase() === VIRTUAL_BASE.address.toLowerCase() + ) { + // if this is from virtual, we'd guess it's due to slippage too low, although it might be due to something else + return SimulationStatus.SlippageTooLow; + } + + // Otherwise we don't wanna guess, just return generic failed. + return SimulationStatus.Failed; default: // we don't know why onchain execution reverted, just return generic failed. return SimulationStatus.Failed; } diff --git a/test/unit/util/tenderlySimulationErrorBreakDown.test.ts b/test/unit/util/tenderlySimulationErrorBreakDown.test.ts index e1a5ac326..be223be84 100644 --- a/test/unit/util/tenderlySimulationErrorBreakDown.test.ts +++ b/test/unit/util/tenderlySimulationErrorBreakDown.test.ts @@ -1,46 +1,56 @@ import { breakDownTenderlySimulationError } from '../../../src/util/tenderlySimulationErrorBreakDown'; -import { SimulationStatus } from '../../../build/main'; +import { + SimulationStatus, + USDC_MAINNET, + USDT_MAINNET, + VIRTUAL_BASE +} from '../../../build/main'; describe('tenderly simulation error break down', () => { it('V3TooMuchRequested', async () => { - const simulationStatus = breakDownTenderlySimulationError('0x739dbe52') + const simulationStatus = breakDownTenderlySimulationError(USDC_MAINNET, USDT_MAINNET, '0x739dbe52') expect(simulationStatus).toEqual(SimulationStatus.SlippageTooLow) }) it('V3TooLittleReceived', async () => { - const simulationStatus = breakDownTenderlySimulationError('0x39d35496') + const simulationStatus = breakDownTenderlySimulationError(USDC_MAINNET, USDT_MAINNET, '0x39d35496') expect(simulationStatus).toEqual(SimulationStatus.SlippageTooLow) }) it('V2TooLittleReceived', async () => { - const simulationStatus = breakDownTenderlySimulationError('0x849eaf98') + const simulationStatus = breakDownTenderlySimulationError(USDC_MAINNET, USDT_MAINNET, '0x849eaf98') expect(simulationStatus).toEqual(SimulationStatus.SlippageTooLow) }) it('V2TooMuchRequested', async () => { - const simulationStatus = breakDownTenderlySimulationError('0x8ab0bc16') + const simulationStatus = breakDownTenderlySimulationError(USDC_MAINNET, USDT_MAINNET, '0x8ab0bc16') expect(simulationStatus).toEqual(SimulationStatus.SlippageTooLow) }) it('INSUFFICIENT_OUTPUT_AMOUNT', async () => { - const simulationStatus = breakDownTenderlySimulationError('0x08c379a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000025556e697377617056323a20494e53554646494349454e545f4f55545055545f414d4f554e54000000000000000000000000000000000000000000000000000000'); + const simulationStatus = breakDownTenderlySimulationError(USDC_MAINNET, USDT_MAINNET, '0x08c379a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000025556e697377617056323a20494e53554646494349454e545f4f55545055545f414d4f554e54000000000000000000000000000000000000000000000000000000'); expect(simulationStatus).toEqual(SimulationStatus.SlippageTooLow) }) it('IIA', async () => { - const simulationStatus = breakDownTenderlySimulationError('0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000034949410000000000000000000000000000000000000000000000000000000000'); + const simulationStatus = breakDownTenderlySimulationError(USDC_MAINNET, USDT_MAINNET, '0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000034949410000000000000000000000000000000000000000000000000000000000'); expect(simulationStatus).toEqual(SimulationStatus.SlippageTooLow) }) it('InsufficientToken', () => { - const simulationStatus = breakDownTenderlySimulationError('0x675cae38'); + const simulationStatus = breakDownTenderlySimulationError(USDC_MAINNET, USDT_MAINNET, '0x675cae38'); expect(simulationStatus).toEqual(SimulationStatus.Failed); }); + it('InsufficientToken Virtual', () => { + const simulationStatus = breakDownTenderlySimulationError(USDC_MAINNET, VIRTUAL_BASE, '0x675cae38'); + expect(simulationStatus).toEqual(SimulationStatus.SlippageTooLow); + }); + it('unknown data', () => { - const simulationStatus = breakDownTenderlySimulationError(undefined); + const simulationStatus = breakDownTenderlySimulationError(USDC_MAINNET, USDT_MAINNET, undefined); expect(simulationStatus).toEqual(SimulationStatus.Failed); }); });