diff --git a/src/features/markets/components/constants.ts b/src/features/markets/components/constants.ts index 9b613c99..10acd846 100644 --- a/src/features/markets/components/constants.ts +++ b/src/features/markets/components/constants.ts @@ -18,19 +18,21 @@ export enum SortColumn { export const GAS_COSTS = { // direct supply through bundler, no approval - BUNDLER_SUPPLY: 180_000, + BUNDLER_SUPPLY: 180_000n, // An additional supply through the bundler, already approved - SINGLE_SUPPLY: 80_000, + SINGLE_SUPPLY: 80_000n, - SINGLE_WITHDRAW: 100_000, + SINGLE_WITHDRAW: 100_000n, // single withdraw + supply - BUNDLER_REBALANCE: 240_000, + BUNDLER_REBALANCE: 240_000n, // directly borrow from Morpho Blue - DIRECT_WITHDRAW: 100_000, + DIRECT_WITHDRAW: 100_000n, }; // additional multiplier for buffer gas. Rabby uses 1.5 -export const GAS_MULTIPLIER = 1.4; +// Using fraction (14/10) to avoid floating-point precision issues with BigInt +export const GAS_MULTIPLIER_NUMERATOR = 14n; +export const GAS_MULTIPLIER_DENOMINATOR = 10n; diff --git a/src/hooks/useMultiMarketSupply.ts b/src/hooks/useMultiMarketSupply.ts index acf7bd9b..4e4fcb0e 100644 --- a/src/hooks/useMultiMarketSupply.ts +++ b/src/hooks/useMultiMarketSupply.ts @@ -10,7 +10,7 @@ import { formatBalance } from '@/utils/balance'; import { getBundlerV2, MONARCH_TX_IDENTIFIER } from '@/utils/morpho'; import { SupportedNetworks } from '@/utils/networks'; import type { Market } from '@/utils/types'; -import { GAS_COSTS, GAS_MULTIPLIER } from '@/features/markets/components/constants'; +import { GAS_COSTS, GAS_MULTIPLIER_NUMERATOR, GAS_MULTIPLIER_DENOMINATOR } from '@/features/markets/components/constants'; import { useERC20Approval } from './useERC20Approval'; import { useStyledToast } from './useStyledToast'; import { useUserMarketsCache } from '@/stores/useUserMarketsCache'; @@ -76,7 +76,7 @@ export function useMultiMarketSupply( const txs: `0x${string}`[] = []; - let gas = undefined; + let gas: bigint | undefined = undefined; try { // Handle ETH wrapping if needed @@ -121,7 +121,7 @@ export function useMultiMarketSupply( ); const numOfSupplies = supplies.length; - gas = GAS_COSTS.BUNDLER_SUPPLY + GAS_COSTS.SINGLE_SUPPLY * (numOfSupplies - 1); + gas = GAS_COSTS.BUNDLER_SUPPLY + GAS_COSTS.SINGLE_SUPPLY * BigInt(numOfSupplies - 1); } tracking.update('supplying'); @@ -164,7 +164,7 @@ export function useMultiMarketSupply( value: useEth ? totalAmount : 0n, // Only add gas for standard approval flow -> skip gas estimation - gas: gas ? BigInt(gas * GAS_MULTIPLIER) : undefined, + gas: gas ? (gas * GAS_MULTIPLIER_NUMERATOR) / GAS_MULTIPLIER_DENOMINATOR : undefined, }); batchAddUserMarkets( diff --git a/src/hooks/useRebalance.ts b/src/hooks/useRebalance.ts index ca497f5d..6f16d2b0 100644 --- a/src/hooks/useRebalance.ts +++ b/src/hooks/useRebalance.ts @@ -6,7 +6,7 @@ import { useTransactionWithToast } from '@/hooks/useTransactionWithToast'; import { useTransactionTracking } from '@/hooks/useTransactionTracking'; import { getBundlerV2, MONARCH_TX_IDENTIFIER } from '@/utils/morpho'; import type { GroupedPosition, RebalanceAction } from '@/utils/types'; -import { GAS_COSTS, GAS_MULTIPLIER } from '@/features/markets/components/constants'; +import { GAS_COSTS, GAS_MULTIPLIER_NUMERATOR, GAS_MULTIPLIER_DENOMINATOR } from '@/features/markets/components/constants'; import { useERC20Approval } from './useERC20Approval'; import { useMorphoAuthorization } from './useMorphoAuthorization'; import { usePermit2 } from './usePermit2'; @@ -255,7 +255,7 @@ export const useRebalance = (groupedPosition: GroupedPosition, onRebalance?: () try { const { withdrawTxs, supplyTxs, allMarketKeys } = generateRebalanceTxData(); - let multicallGas = undefined; + let multicallGas: bigint | undefined = undefined; if (usePermit2Setting) { // --- Permit2 Flow --- @@ -318,14 +318,14 @@ export const useRebalance = (groupedPosition: GroupedPosition, onRebalance?: () multicallGas = GAS_COSTS.BUNDLER_REBALANCE; if (supplyTxs.length > 1) { - multicallGas += GAS_COSTS.SINGLE_SUPPLY * (supplyTxs.length - 1); + multicallGas += GAS_COSTS.SINGLE_SUPPLY * BigInt(supplyTxs.length - 1); } if (withdrawTxs.length > 1) { - multicallGas += GAS_COSTS.SINGLE_WITHDRAW * (withdrawTxs.length - 1); + multicallGas += GAS_COSTS.SINGLE_WITHDRAW * BigInt(withdrawTxs.length - 1); } - console.log('multicallGas', multicallGas); + console.log('multicallGas', multicallGas.toString()); } // Step Final: Execute multicall @@ -341,7 +341,7 @@ export const useRebalance = (groupedPosition: GroupedPosition, onRebalance?: () to: bundlerAddress, data: multicallTx, chainId: groupedPosition.chainId, - gas: multicallGas ? BigInt(multicallGas * GAS_MULTIPLIER) : undefined, + gas: multicallGas ? (multicallGas * GAS_MULTIPLIER_NUMERATOR) / GAS_MULTIPLIER_DENOMINATOR : undefined, }); batchAddUserMarkets( diff --git a/src/hooks/useSupplyMarket.ts b/src/hooks/useSupplyMarket.ts index 2c258396..e7556d40 100644 --- a/src/hooks/useSupplyMarket.ts +++ b/src/hooks/useSupplyMarket.ts @@ -12,7 +12,7 @@ import { useTransactionTracking } from '@/hooks/useTransactionTracking'; import { formatBalance } from '@/utils/balance'; import { getBundlerV2, MONARCH_TX_IDENTIFIER } from '@/utils/morpho'; import type { Market } from '@/utils/types'; -import { GAS_COSTS, GAS_MULTIPLIER } from '@/features/markets/components/constants'; +import { GAS_COSTS, GAS_MULTIPLIER_NUMERATOR, GAS_MULTIPLIER_DENOMINATOR } from '@/features/markets/components/constants'; export type SupplyStepType = 'approve' | 'signing' | 'supplying'; @@ -163,7 +163,7 @@ export function useSupplyMarket(market: Market, onSuccess?: () => void): UseSupp try { const txs: `0x${string}`[] = []; - let gas = undefined; + let gas: bigint | undefined = undefined; if (useEth) { txs.push( @@ -244,7 +244,7 @@ export function useSupplyMarket(market: Market, onSuccess?: () => void): UseSupp value: useEth ? supplyAmount : 0n, // Only add gas for standard approval flow -> skip gas estimation - gas: gas ? BigInt(gas * GAS_MULTIPLIER) : undefined, + gas: gas ? (gas * GAS_MULTIPLIER_NUMERATOR) / GAS_MULTIPLIER_DENOMINATOR : undefined, }); batchAddUserMarkets([ diff --git a/src/hooks/useVaultV2Deposit.ts b/src/hooks/useVaultV2Deposit.ts index 0393c668..03b67bd1 100644 --- a/src/hooks/useVaultV2Deposit.ts +++ b/src/hooks/useVaultV2Deposit.ts @@ -10,7 +10,7 @@ import { useTransactionWithToast } from '@/hooks/useTransactionWithToast'; import { useTransactionTracking } from '@/hooks/useTransactionTracking'; import { formatBalance } from '@/utils/balance'; import { getBundlerV2, MONARCH_TX_IDENTIFIER } from '@/utils/morpho'; -import { GAS_COSTS, GAS_MULTIPLIER } from '@/features/markets/components/constants'; +import { GAS_COSTS, GAS_MULTIPLIER_NUMERATOR, GAS_MULTIPLIER_DENOMINATOR } from '@/features/markets/components/constants'; export type VaultDepositStepType = 'approve' | 'signing' | 'depositing'; @@ -141,7 +141,7 @@ export function useVaultV2Deposit({ const executeDepositTransaction = useCallback(async () => { try { const txs: `0x${string}`[] = []; - let gas = undefined; + let gas: bigint | undefined = undefined; if (usePermit2Setting) { // Permit2 flow: Sign permit and use bundler to deposit @@ -200,7 +200,7 @@ export function useVaultV2Deposit({ value: 0n, // Only add gas for standard approval flow -> skip gas estimation - gas: gas ? BigInt(gas * GAS_MULTIPLIER) : undefined, + gas: gas ? (gas * GAS_MULTIPLIER_NUMERATOR) / GAS_MULTIPLIER_DENOMINATOR : undefined, }); tracking.complete();