diff --git a/src/Managing.Application/Trading/Commands/OpenPositionRequest.cs b/src/Managing.Application/Trading/Commands/OpenPositionRequest.cs index 49e1c61e..ea28c1ae 100644 --- a/src/Managing.Application/Trading/Commands/OpenPositionRequest.cs +++ b/src/Managing.Application/Trading/Commands/OpenPositionRequest.cs @@ -32,7 +32,7 @@ namespace Managing.Application.Trading.Commands if (amountToTrade <= Constants.GMX.Config.MinimumPositionAmount) { - throw new ArgumentException("Bot trading balance must be greater than zero", nameof(amountToTrade)); + throw new ArgumentException("Bot trading balance must be greater than : 5usdc", nameof(amountToTrade)); } AmountToTrade = amountToTrade; diff --git a/src/Managing.Web3Proxy/src/generated/gmxsdk/utils/callContract.ts b/src/Managing.Web3Proxy/src/generated/gmxsdk/utils/callContract.ts index fc0d55c8..bdd66b5c 100644 --- a/src/Managing.Web3Proxy/src/generated/gmxsdk/utils/callContract.ts +++ b/src/Managing.Web3Proxy/src/generated/gmxsdk/utils/callContract.ts @@ -148,9 +148,12 @@ export async function callContract( const txnInstance = { ...txnOpts }; // Get gas limit - const gasLimit = opts.gasLimit - ? BigInt(opts.gasLimit) - : await getGasLimit( + let gasLimit: bigint; + if (opts.gasLimit) { + gasLimit = BigInt(opts.gasLimit); + } else { + try { + gasLimit = await getGasLimit( client, sdk.config.account as Address, contractAddress, @@ -159,6 +162,21 @@ export async function callContract( params, opts.value !== undefined ? BigInt(opts.value) : undefined ); + } catch (gasEstimateError: any) { + // Check if the error is related to allowance (common with stale RPC state) + const errorMessage = gasEstimateError?.message?.toLowerCase() || ''; + if (errorMessage.includes('allowance') || errorMessage.includes('erc20')) { + console.warn('⚠️ Gas estimation failed due to potential stale RPC state, using fallback gas limit'); + console.warn('Gas estimate error:', errorMessage); + // Use a conservative fallback gas limit for GMX multicall transactions + // GMX orders typically use 2-5M gas depending on complexity + gasLimit = 5000000n; // 5M gas limit as fallback + } else { + // Re-throw if it's a different error + throw gasEstimateError; + } + } + } txnInstance.gas = gasLimit; // Get gas price diff --git a/src/Managing.Web3Proxy/src/plugins/custom/gmx.ts b/src/Managing.Web3Proxy/src/plugins/custom/gmx.ts index 02677f45..0d3d6817 100644 --- a/src/Managing.Web3Proxy/src/plugins/custom/gmx.ts +++ b/src/Managing.Web3Proxy/src/plugins/custom/gmx.ts @@ -748,7 +748,7 @@ export const openGmxPositionImpl = async ( marketAddress: marketInfo.marketTokenAddress, payTokenAddress: collateralToken.address, collateralTokenAddress: collateralToken.address, - allowedSlippageBps: 50, // 0.5% slippage + allowedSlippageBps: 55, // 0.55% slippage leverage: leverageBps, skipSimulation: true, referralCodeForTxn: encodeReferralCode("kaigen_ai"), diff --git a/src/Managing.Web3Proxy/src/plugins/custom/privy.ts b/src/Managing.Web3Proxy/src/plugins/custom/privy.ts index 7507e577..4b748a60 100644 --- a/src/Managing.Web3Proxy/src/plugins/custom/privy.ts +++ b/src/Managing.Web3Proxy/src/plugins/custom/privy.ts @@ -413,6 +413,7 @@ export async function signPrivyMessage( * @param spenderAddress The contract address to approve * @param chainId The chain ID * @param amount The amount to approve (optional, defaults to max amount) + * @param waitForConfirmation Whether to wait for the transaction to be confirmed on-chain (default: true) * @returns The transaction hash */ export const approveContractImpl = async ( @@ -421,6 +422,7 @@ export const approveContractImpl = async ( spenderAddress: string, chainId?: number, amount?: bigint, + waitForConfirmation: boolean = true ): Promise => { try { // Create contract interface for ERC20 token @@ -450,6 +452,17 @@ export const approveContractImpl = async ( }, } as any); + // Wait for the approval transaction to be confirmed to avoid race conditions + if (waitForConfirmation) { + console.log(`⏳ Waiting for approval transaction to be confirmed: ${hash}`); + const sdk = await getClientForAddress(walletAddress); + const receipt = await sdk.publicClient.waitForTransactionReceipt({ + hash: hash as `0x${string}`, + confirmations: 1 // Wait for at least 1 confirmation + }); + console.log(`✅ Approval transaction confirmed in block ${receipt.blockNumber}`); + } + return hash; } catch (error) { console.error('Error approving contract:', error);