From ba43505d748b336ed7b218d5f553bd5b1636775c Mon Sep 17 00:00:00 2001 From: Marcel Ebert Date: Sat, 24 Jan 2026 19:54:49 +0000 Subject: [PATCH] Normalize gas limit and value to BigInt string format --- .../shared/src/services/squidrouter/route.ts | 55 ++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/packages/shared/src/services/squidrouter/route.ts b/packages/shared/src/services/squidrouter/route.ts index 1918fd6f9..c5ef315c3 100644 --- a/packages/shared/src/services/squidrouter/route.ts +++ b/packages/shared/src/services/squidrouter/route.ts @@ -6,6 +6,57 @@ import { AXL_USDC_MOONBEAM, EvmTokenDetails, EvmTransactionData, getNetworkId, N import logger from "../../logger"; import { getSquidRouterConfig, squidRouterConfigBase } from "./config"; +/** + * Normalizes a numeric string to a format that BigInt can parse. + * Handles scientific notation (e.g., "1.5e18") and decimal strings (e.g., "123.456") + * by converting them to integer strings, truncating any fractional part. + */ +function normalizeBigIntString(value: string): string { + if (!value || value === "") { + return "0"; + } + + // If it's already a valid integer string (decimal or hex), return as-is + if (/^-?\d+$/.test(value) || /^0x[0-9a-fA-F]+$/i.test(value)) { + return value; + } + + // Handle scientific notation and decimals by parsing as Number first, then converting + // This will truncate any fractional part + try { + const num = Number(value); + if (Number.isNaN(num) || !Number.isFinite(num)) { + logger.current.warn(`Invalid numeric value for BigInt conversion: ${value}, defaulting to 0`); + return "0"; + } + // Use BigInt on the truncated integer value to avoid precision issues with large numbers + // For very large numbers, we need to handle them specially + if (Math.abs(num) > Number.MAX_SAFE_INTEGER) { + // For scientific notation with large exponents, parse manually + const match = value.match(/^(-?\d+\.?\d*)[eE]([+-]?\d+)$/); + if (match) { + const [, mantissa, exponent] = match; + const exp = parseInt(exponent, 10); + const [intPart, decPart = ""] = mantissa.replace("-", "").split("."); + const sign = mantissa.startsWith("-") ? "-" : ""; + const totalDigits = intPart + decPart; + const zerosNeeded = exp - decPart.length; + if (zerosNeeded >= 0) { + return sign + totalDigits + "0".repeat(zerosNeeded); + } else { + // Truncate decimal part + return sign + totalDigits.slice(0, totalDigits.length + zerosNeeded) || "0"; + } + } + } + // For smaller numbers, Math.trunc works fine + return BigInt(Math.trunc(num)).toString(); + } catch (e) { + logger.current.warn(`Failed to normalize BigInt string: ${value}, error: ${e}`); + return "0"; + } +} + const SQUIDROUTER_BASE_URL = "https://v2.api.squidrouter.com/v2"; export { splitReceiverABI }; @@ -326,11 +377,11 @@ export async function createTransactionDataFromRoute({ const swapData: EvmTransactionData = { data: transactionRequest.data as `0x${string}`, - gas: transactionRequest.gasLimit, + gas: normalizeBigIntString(transactionRequest.gasLimit), maxFeePerGas: maxFeePerGas.toString(), maxPriorityFeePerGas: (maxPriorityFeePerGas ?? maxFeePerGas).toString(), to: transactionRequest.target as `0x${string}`, - value: swapValue ?? transactionRequest.value + value: normalizeBigIntString(swapValue ?? transactionRequest.value) }; if (nonce !== undefined) {