@@ -421,6 +421,13 @@ export const SendConfirm = () => {
421421 : gasLimitCandidate ;
422422 maxSendGasLimit = gasLimit ;
423423
424+ // Add a conservative fixed buffer for MAX sends.
425+ // Some networks can require additional intrinsic costs or see small fee variance
426+ // between estimation and execution. We intentionally send slightly less than MAX.
427+ // Keep this as a small *absolute* reserve (not a %), since these extra costs are
428+ // typically additive rather than proportional to L2 execution gas.
429+ const maxSendBufferWei = parseUnits ( '0.000001' , 'ether' ) ; // 0.000001 native
430+
424431 if ( isEIP1559Compatible ) {
425432 // EIP-1559 transaction
426433 const maxFeePerGasWei = parseUnits (
@@ -430,12 +437,12 @@ export const SendConfirm = () => {
430437 9
431438 ) ;
432439 const maxGasFeeWei = gasLimit . mul ( maxFeePerGasWei ) ;
433- value = value . sub ( maxGasFeeWei ) ;
440+ value = value . sub ( maxGasFeeWei ) . sub ( maxSendBufferWei ) ;
434441 } else {
435442 // Legacy transaction
436443 const gasPriceWei = BigNumber . from ( gasPrice ) ;
437444 const gasFeeWei = gasLimit . mul ( gasPriceWei ) ;
438- value = value . sub ( gasFeeWei ) ;
445+ value = value . sub ( gasFeeWei ) . sub ( maxSendBufferWei ) ;
439446 }
440447
441448 // Ensure value doesn't go negative
@@ -455,7 +462,6 @@ export const SendConfirm = () => {
455462 {
456463 ...restTx ,
457464 to : destinationTo ,
458- isMaxSend : Boolean ( basicTxValues . isMax ) ,
459465 value : value . toHexString ( ) , // Convert to hex string to avoid out-of-safe-range error
460466 gasPrice : BigNumber . from ( gasPrice ) . toHexString ( ) , // Use BigNumber for precision
461467 gasLimit : (
@@ -510,7 +516,6 @@ export const SendConfirm = () => {
510516 {
511517 ...restTx ,
512518 to : destinationTo ,
513- isMaxSend : Boolean ( basicTxValues . isMax ) ,
514519 value : value . toHexString ( ) , // Convert to hex string to avoid out-of-safe-range error
515520 maxPriorityFeePerGas : parseUnits (
516521 Boolean (
@@ -547,84 +552,6 @@ export const SendConfirm = () => {
547552
548553 return ;
549554 } catch ( error : any ) {
550- // For MAX sends, if we get insufficient funds error, retry with a buffer
551- // This can happen due to gas price fluctuations between estimation and execution
552- if (
553- basicTxValues . isMax &&
554- error . message ?. includes ( 'insufficient funds' )
555- ) {
556- const buffer = BigNumber . from ( '100000' ) ;
557- const reducedValue = value . sub ( buffer ) ;
558-
559- if ( reducedValue . gt ( 0 ) ) {
560- const retryTxObject = {
561- ...restTx ,
562- to : destinationTo ,
563- // This retry intentionally sends slightly less than MAX to add a buffer.
564- // Do NOT mark as isMaxSend, otherwise sysweb3 will recompute the value
565- // and remove this buffer.
566- isMaxSend : false ,
567- value : reducedValue . toHexString ( ) , // Convert to hex string to avoid out-of-safe-range error
568- maxPriorityFeePerGas : parseUnits (
569- Boolean (
570- customFee . isCustom && customFee . maxPriorityFeePerGas > 0
571- )
572- ? safeToFixed ( customFee . maxPriorityFeePerGas )
573- : safeToFixed ( fee . maxPriorityFeePerGas ) ,
574- 9
575- ) ,
576- maxFeePerGas : parseUnits (
577- String (
578- Boolean ( customFee . isCustom && customFee . maxFeePerGas > 0 )
579- ? safeToFixed ( customFee . maxFeePerGas )
580- : safeToFixed ( fee . maxFeePerGas )
581- ) ,
582- 9
583- ) ,
584- gasLimit :
585- maxSendGasLimit ||
586- BigNumber . from (
587- validateCustomGasLimit
588- ? customFee . gasLimit
589- : fee . gasLimit || basicTxValues . defaultGasLimit || 42000
590- ) ,
591- } ;
592-
593- try {
594- // Use atomic wrapper for retry
595- await controllerEmitter (
596- [ 'wallet' , 'sendAndSaveEthTransaction' ] ,
597- [ retryTxObject , ! isEIP1559Compatible ] ,
598- activeAccount . isTrezorWallet || activeAccount . isLedgerWallet
599- ? 300000 // 5 minutes timeout for hardware wallet operations
600- : 10000 // Default 10 seconds for regular wallets
601- ) ;
602-
603- setConfirmed ( true ) ;
604- setLoading ( false ) ;
605- return ; // Exit early on success
606- } catch ( retryError ) {
607- // If retry also fails, handle with specific error messages
608- const wasHandledSpecifically = handleTransactionError (
609- retryError ,
610- alert ,
611- t ,
612- activeAccount ,
613- activeNetwork ,
614- basicTxValues
615- ) ;
616-
617- if ( ! wasHandledSpecifically ) {
618- logError ( 'error ETH retry' , 'Transaction' , retryError ) ;
619- alert . error ( t ( 'send.cantCompleteTxs' ) ) ;
620- }
621-
622- setLoading ( false ) ;
623- return ;
624- }
625- }
626- }
627-
628555 // Handle specific errors (blacklist, cancellation, etc.) with detailed messages
629556 const wasHandledSpecifically = handleTransactionError (
630557 error ,
0 commit comments