From 96a05295b1ec3ff8e7644b172cfb6d4686da152d Mon Sep 17 00:00:00 2001 From: chad-js Date: Fri, 13 Feb 2026 15:15:06 -0500 Subject: [PATCH 1/2] feat: update tx sim errors --- .../leverage-token-mint-modal/ErrorStep.tsx | 1 + .../leverage-token-redeem-modal/ErrorStep.tsx | 1 + .../leverage-tokens/utils/errorDisplay.tsx | 37 ++++++- src/features/leverage-tokens/utils/errors.ts | 53 ++++++--- .../leverage-tokens/utils/errors.test.ts | 103 ++++++++++++++++++ 5 files changed, 178 insertions(+), 17 deletions(-) create mode 100644 tests/unit/features/leverage-tokens/utils/errors.test.ts diff --git a/src/features/leverage-tokens/components/leverage-token-mint-modal/ErrorStep.tsx b/src/features/leverage-tokens/components/leverage-token-mint-modal/ErrorStep.tsx index ca579374..3d14a690 100644 --- a/src/features/leverage-tokens/components/leverage-token-mint-modal/ErrorStep.tsx +++ b/src/features/leverage-tokens/components/leverage-token-mint-modal/ErrorStep.tsx @@ -12,6 +12,7 @@ export function ErrorStep({ error, onRetry, onClose }: ErrorStepProps) { const { icon, title, message, showRetry, severity, technicalDetails } = getErrorDisplay( error || '', 'Transaction Failed', + 'mintLt', ) const bgClass = severity === 'warning' diff --git a/src/features/leverage-tokens/components/leverage-token-redeem-modal/ErrorStep.tsx b/src/features/leverage-tokens/components/leverage-token-redeem-modal/ErrorStep.tsx index 4606ffac..aff59631 100644 --- a/src/features/leverage-tokens/components/leverage-token-redeem-modal/ErrorStep.tsx +++ b/src/features/leverage-tokens/components/leverage-token-redeem-modal/ErrorStep.tsx @@ -12,6 +12,7 @@ export function ErrorStep({ error, onRetry, onClose }: ErrorStepProps) { const { icon, title, message, showRetry, severity, technicalDetails } = getErrorDisplay( error || '', 'Redemption Failed', + 'redeemLt', ) const bgClass = severity === 'warning' diff --git a/src/features/leverage-tokens/utils/errorDisplay.tsx b/src/features/leverage-tokens/utils/errorDisplay.tsx index 8708f43d..10da490b 100644 --- a/src/features/leverage-tokens/utils/errorDisplay.tsx +++ b/src/features/leverage-tokens/utils/errorDisplay.tsx @@ -19,11 +19,12 @@ export interface ErrorDisplayConfig { export function getErrorDisplay( error: string, defaultTitle: string = 'Transaction Failed', + txType?: 'mintLt' | 'redeemLt', ): ErrorDisplayConfig { // Try to classify the error first let classifiedError: LeverageTokenError try { - classifiedError = classifyError(error) + classifiedError = classifyError(error, txType) } catch { classifiedError = { type: 'UNKNOWN', message: error } } @@ -87,14 +88,42 @@ export function getErrorDisplay( case 'SLIPPAGE_EXCEEDED': return { icon: , - title: 'Slippage Tolerance Exceeded', - message: - 'The price moved beyond your slippage tolerance. Try increasing your slippage tolerance or retry the transaction.', + title: 'Swap Slippage Tolerance Exceeded', + message: `The spot price moved beyond your slippage tolerance. Try decreasing your swap slippage tolerance, increasing the ${txType === 'mintLt' ? 'leverage token' : 'collateral'} adjustment parameter, or retry the transaction.`, showRetry: true, severity: 'warning', technicalDetails: error, } + case 'LT_SHARE_SLIPPAGE_EXCEEDED': + return { + icon: , + title: 'Leverage Token Slippage Exceeded', + message: + 'The Leverage Token share price moved beyond your slippage tolerance. Try decreasing your swap slippage tolerance, increasing the Leverage Token slippage tolerance, or retry the transaction.', + showRetry: true, + severity: 'warning', + } + + case 'LT_COLLATERAL_SLIPPAGE_EXCEEDED': + return { + icon: , + title: 'Leverage Token Collateral Slippage Exceeded', + message: + 'The Leverage Token collateral price moved beyond your slippage tolerance. Try decreasing your swap slippage tolerance, increasing the collateral slippage tolerance, or retry the transaction.', + showRetry: true, + severity: 'warning', + } + + case 'INSUFFICIENT_ASSETS_FOR_FLASH_LOAN_REPAYMENT': + return { + icon: , + title: 'Insufficient Assets for Flash Loan Repayment', + message: `Unable to repay flash loan. Try decreasing your swap slippage tolerance, increasing the ${txType === 'mintLt' ? 'flash loan adjustment' : 'collateral swap adjustment'} parameter, or retry the transaction.`, + showRetry: true, + severity: 'error', + } + default: // For unknown errors, check if it's a user rejection by looking for common patterns if ( diff --git a/src/features/leverage-tokens/utils/errors.ts b/src/features/leverage-tokens/utils/errors.ts index 42720806..aba70b61 100644 --- a/src/features/leverage-tokens/utils/errors.ts +++ b/src/features/leverage-tokens/utils/errors.ts @@ -10,16 +10,19 @@ export type LeverageTokenError = | { type: 'USER_REJECTED'; code: 4001 } | { type: 'CHAIN_MISMATCH'; expected: number; actual: number } | { type: 'UNKNOWN'; message: string; originalError?: unknown } + | { type: 'LT_SHARE_SLIPPAGE_EXCEEDED' } + | { type: 'LT_COLLATERAL_SLIPPAGE_EXCEEDED' } + | { type: 'INSUFFICIENT_ASSETS_FOR_FLASH_LOAN_REPAYMENT' } /** * Classify errors into actionable types * User errors (4001, 4902) should not be sent to Sentry */ -export function classifyError(e: unknown): LeverageTokenError { +export function classifyError(e: unknown, txType?: 'mintLt' | 'redeemLt'): LeverageTokenError { // Handle string input directly if (typeof e === 'string') { const error = { message: e } - return classifyErrorFromObject(error) + return classifyErrorFromObject(error, txType) } const error = e as { @@ -32,18 +35,21 @@ export function classifyError(e: unknown): LeverageTokenError { message?: string } - return classifyErrorFromObject(error) + return classifyErrorFromObject(error, txType) } -function classifyErrorFromObject(error: { - code?: number - cause?: { code?: number } - expectedChainId?: number - actualChainId?: number - reason?: string - data?: { message?: string } - message?: string -}): LeverageTokenError { +function classifyErrorFromObject( + error: { + code?: number + cause?: { code?: number } + expectedChainId?: number + actualChainId?: number + reason?: string + data?: { message?: string } + message?: string + }, + txType?: 'mintLt' | 'redeemLt', +): LeverageTokenError { // User rejected transaction if (error?.code === 4001 || error?.cause?.code === 4001) { return { type: 'USER_REJECTED', code: 4001 } @@ -113,9 +119,30 @@ function classifyErrorFromObject(error: { // Check for slippage-related error signatures in the raw message const rawMessage = error?.message || '' + + if (txType === 'mintLt' && rawMessage.includes('0x76baadda')) { + return { + type: 'LT_SHARE_SLIPPAGE_EXCEEDED', + } + } + + if (txType === 'redeemLt' && (rawMessage.includes('0x76baadda') || 'CollateralSlippageTooHigh')) { + return { + type: 'LT_COLLATERAL_SLIPPAGE_EXCEEDED', + } + } + + if ( + (txType === 'mintLt' || txType === 'redeemLt') && + rawMessage.includes('transferFrom reverted') + ) { + return { + type: 'INSUFFICIENT_ASSETS_FOR_FLASH_LOAN_REPAYMENT', + } + } + if ( rawMessage.includes('0x5a046737') || // Common slippage signature - rawMessage.includes('0x76baadda') || // Another slippage signature rawMessage.includes('SlippageExceeded') || rawMessage.includes('SlippageToleranceExceeded') || rawMessage.includes('PriceImpactTooHigh') || diff --git a/tests/unit/features/leverage-tokens/utils/errors.test.ts b/tests/unit/features/leverage-tokens/utils/errors.test.ts new file mode 100644 index 00000000..04458c58 --- /dev/null +++ b/tests/unit/features/leverage-tokens/utils/errors.test.ts @@ -0,0 +1,103 @@ +import { describe, expect, it } from 'vitest' +import { classifyError } from '@/features/leverage-tokens/utils/errors' + +describe('classifyError', () => { + describe('LT_SHARE_SLIPPAGE_EXCEEDED (mint)', () => { + it('returns LT_SHARE_SLIPPAGE_EXCEEDED when txType is mintLt and message contains 0x76baadda', () => { + const error = { + message: + 'The contract function "deposit" reverted. Error signature 0x76baadda. Some other text.', + } + expect(classifyError(error, 'mintLt')).toEqual({ + type: 'LT_SHARE_SLIPPAGE_EXCEEDED', + }) + }) + + it('does not return LT_SHARE_SLIPPAGE_EXCEEDED when txType is mintLt but message lacks 0x76baadda', () => { + const error = { message: 'transferFrom reverted' } + expect(classifyError(error, 'mintLt')).not.toEqual({ + type: 'LT_SHARE_SLIPPAGE_EXCEEDED', + }) + }) + + it('does not return LT_SHARE_SLIPPAGE_EXCEEDED when message contains 0x76baadda but txType is not mintLt', () => { + const error = { message: 'Revert 0x76baadda' } + expect(classifyError(error, 'redeemLt')).toEqual({ + type: 'LT_COLLATERAL_SLIPPAGE_EXCEEDED', + }) + expect(classifyError(error)).not.toEqual({ + type: 'LT_SHARE_SLIPPAGE_EXCEEDED', + }) + }) + }) + + describe('LT_COLLATERAL_SLIPPAGE_EXCEEDED (redeem)', () => { + it('returns LT_COLLATERAL_SLIPPAGE_EXCEEDED when txType is redeemLt and message contains 0x76baadda', () => { + const error = { message: 'Reverted with 0x76baadda' } + expect(classifyError(error, 'redeemLt')).toEqual({ + type: 'LT_COLLATERAL_SLIPPAGE_EXCEEDED', + }) + }) + + it('returns LT_COLLATERAL_SLIPPAGE_EXCEEDED when txType is redeemLt and message contains CollateralSlippageTooHigh', () => { + const error = { message: 'CollateralSlippageTooHigh' } + expect(classifyError(error, 'redeemLt')).toEqual({ + type: 'LT_COLLATERAL_SLIPPAGE_EXCEEDED', + }) + }) + + it('returns LT_COLLATERAL_SLIPPAGE_EXCEEDED when txType is redeemLt even without slippage text (current behavior)', () => { + const error = { message: 'Some other revert' } + expect(classifyError(error, 'redeemLt')).toEqual({ + type: 'LT_COLLATERAL_SLIPPAGE_EXCEEDED', + }) + }) + + it('does not return LT_COLLATERAL_SLIPPAGE_EXCEEDED when txType is not redeemLt', () => { + const error = { message: '0x76baadda' } + expect(classifyError(error, 'mintLt')).toEqual({ + type: 'LT_SHARE_SLIPPAGE_EXCEEDED', + }) + expect(classifyError(error)).toEqual({ + type: 'UNKNOWN', + message: '0x76baadda', + originalError: error, + }) + }) + }) + + describe('INSUFFICIENT_ASSETS_FOR_FLASH_LOAN_REPAYMENT', () => { + it('returns INSUFFICIENT_ASSETS_FOR_FLASH_LOAN_REPAYMENT when txType is mintLt and message contains transferFrom reverted', () => { + const error = { + message: + 'The contract function "deposit" reverted with the following reason:\ntransferFrom reverted\n\nContract Call:', + } + expect(classifyError(error, 'mintLt')).toEqual({ + type: 'INSUFFICIENT_ASSETS_FOR_FLASH_LOAN_REPAYMENT', + }) + }) + + it('returns INSUFFICIENT_ASSETS_FOR_FLASH_LOAN_REPAYMENT when txType is redeemLt and message contains transferFrom reverted', () => { + const error = { message: 'transferFrom reverted' } + expect(classifyError(error, 'redeemLt')).toEqual({ + type: 'LT_COLLATERAL_SLIPPAGE_EXCEEDED', + }) + }) + + it('does not return INSUFFICIENT_ASSETS_FOR_FLASH_LOAN_REPAYMENT when message does not contain transferFrom reverted', () => { + const error = { message: 'Some other error' } + expect(classifyError(error, 'mintLt')).not.toEqual({ + type: 'INSUFFICIENT_ASSETS_FOR_FLASH_LOAN_REPAYMENT', + }) + }) + + it('does not return INSUFFICIENT_ASSETS_FOR_FLASH_LOAN_REPAYMENT when txType is omitted', () => { + const error = { message: 'transferFrom reverted' } + expect(classifyError(error)).toEqual({ + type: 'UNKNOWN', + message: 'transferFrom reverted', + originalError: error, + }) + }) + }) +}) From f613b315f54d7a891379bfcae88b8e9048d2eb5d Mon Sep 17 00:00:00 2001 From: chad-js Date: Tue, 24 Feb 2026 13:12:55 -0600 Subject: [PATCH 2/2] fix revert error check --- src/features/leverage-tokens/utils/errors.ts | 5 ++++- tests/unit/features/leverage-tokens/utils/errors.test.ts | 8 +++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/features/leverage-tokens/utils/errors.ts b/src/features/leverage-tokens/utils/errors.ts index aba70b61..19af78c4 100644 --- a/src/features/leverage-tokens/utils/errors.ts +++ b/src/features/leverage-tokens/utils/errors.ts @@ -126,7 +126,10 @@ function classifyErrorFromObject( } } - if (txType === 'redeemLt' && (rawMessage.includes('0x76baadda') || 'CollateralSlippageTooHigh')) { + if ( + txType === 'redeemLt' && + (rawMessage.includes('0x76baadda') || rawMessage.includes('CollateralSlippageTooHigh')) + ) { return { type: 'LT_COLLATERAL_SLIPPAGE_EXCEEDED', } diff --git a/tests/unit/features/leverage-tokens/utils/errors.test.ts b/tests/unit/features/leverage-tokens/utils/errors.test.ts index 04458c58..4c20dd81 100644 --- a/tests/unit/features/leverage-tokens/utils/errors.test.ts +++ b/tests/unit/features/leverage-tokens/utils/errors.test.ts @@ -46,10 +46,12 @@ describe('classifyError', () => { }) }) - it('returns LT_COLLATERAL_SLIPPAGE_EXCEEDED when txType is redeemLt even without slippage text (current behavior)', () => { + it('does not return LT_COLLATERAL_SLIPPAGE_EXCEEDED when txType is redeemLt but message is not CollateralSlippageTooHigh or 0x76baadda', () => { const error = { message: 'Some other revert' } expect(classifyError(error, 'redeemLt')).toEqual({ - type: 'LT_COLLATERAL_SLIPPAGE_EXCEEDED', + type: 'UNKNOWN', + message: 'Some other revert', + originalError: error, }) }) @@ -80,7 +82,7 @@ describe('classifyError', () => { it('returns INSUFFICIENT_ASSETS_FOR_FLASH_LOAN_REPAYMENT when txType is redeemLt and message contains transferFrom reverted', () => { const error = { message: 'transferFrom reverted' } expect(classifyError(error, 'redeemLt')).toEqual({ - type: 'LT_COLLATERAL_SLIPPAGE_EXCEEDED', + type: 'INSUFFICIENT_ASSETS_FOR_FLASH_LOAN_REPAYMENT', }) })