How can i fix this problem. For trading sometimes i got this error INSUFFICIENT_FUNDS

This is my trade code

const fireblocksSettings = require("../fireblocksSettings");
const mathOps = require("../utils/math");
var logger = require("../logger");
var transactionFactory = require("../factories/TransactionFactory");
var AggregatorService = require("./AggregatorService");
const aggregatorService = new AggregatorService();
const TransactionService = require("./TransactionService");
const appConfig = new (require(`../config.${process.env.NODE_ENV}`))();

const FireblocksSDK = require("fireblocks-sdk").FireblocksSDK;
const apiSecret = appConfig.fireblocksSecret;
const apiKey = appConfig.fireblocksKey;
const fireblocks = new FireblocksSDK(apiSecret, apiKey);
const FireblocksTransactionSchema = require("../schemas/transaction");

const ethers = require("ethers");
const {
  FireblocksWeb3Provider,
  ChainId, 
} = require("@fireblocks/fireblocks-web3-provider");

const constants = require("../message-queue/RabbitListenerConstants");
var rabbitMqFactory = require("../messageBrokerFactory");
var messageBus = rabbitMqFactory.getBroker();
const TransactionUpdate = require("../message-queue/TransactionUpdate");
const TokenService = require("../services/TokenService");

class TradeService {
  constructor(arg, securityContext, tenantId, uid) {
    this.arg = arg;
    logger.info("user input value is Shahid-1", arg)
    this.arg.tradeCommission = mathOps.getTradeCommission(arg.amount);
    this.arg.usersCut = mathOps.getUsersCut(
      arg.amount,
      this.arg.tradeCommission,
    );
    logger.info("user cut value is  Shahid ", this.arg.usersCut)
    

    this.securityContext = securityContext;
    const eip1193Provider = new FireblocksWeb3Provider({
      privateKey: apiSecret,
      apiKey: apiKey,
      vaultAccountIds: this.arg.vaultId,
      chainId: ChainId.BSC,
    });

    this.provider = new ethers.providers.Web3Provider(eip1193Provider);
    this.tenantId = tenantId;
    this.auth0Id = uid;
  }

  securityCheck = async () => {
    let doApprove = false;
    let allowance = null;
    let balance = null;

    logger.info(
      `its ${this.arg.inTokenSymbol} | ots ${this.arg.outTokenSymbol}`,
    );
    if (this.arg.fireblocksAssetId == fireblocksSettings.baseAssetId) {
      const vaultAsset = await fireblocks.getVaultAccountAsset(
        this.arg.vaultId,
        this.arg.fireblocksAssetId,
      );
      balance = vaultAsset.total;
    } else {
      const signer = await this.provider.getSigner();
      const signerAddress = await signer.getAddress();
      const contract = new ethers.Contract(
        this.arg.inTokenAddress,
        fireblocksSettings.ooABI,
        signer,
      );
      const balanceRaw = await contract.balanceOf(signerAddress);
      const decimals = await contract.decimals();
      balance = ethers.utils.formatUnits(
        ethers.BigNumber.from(balanceRaw),
        decimals,
      );

      allowance = ethers.utils.formatUnits(
        await contract.allowance(
          signerAddress,
          fireblocksSettings.openOceanContractAddress,
        ),
        decimals,
      );

      logger.info(
        "__allowance:" +
          allowance +
          " balance:" +
          balance +
          " decimals:" +
          decimals,
      );
      if (allowance < this.arg.amount) {
        doApprove = true;
        logger.info("__allowance needed");
      }
    }

    if (balance < this.arg.amount) {
      // throw new Error('Insufficient balance. Balance:'+balance+' Amount:'+this.arg.amount);
      await this.saveFailedTxn();
      await this.sendRabbitMessage();
      throw {
        type: "INSUFFICIENT_BALANCE",
        message: `balance: ${balance}, amount: ${this.arg.amount}`,
      };
    }

    this.userVaultAddress = await this.getAccountAddress(
      this.arg.vaultId,
      this.arg.fireblocksAssetId,
    );

    let gasPriceRaw = await this.provider.getGasPrice();
    let gasPrice = ethers.utils.formatUnits(gasPriceRaw, "gwei");
    logger.info('After Before acessing the  tradeResult.data');

    let tradeResult = await aggregatorService.getCryptoTradeSwapQuote({
      inTokenAddress: this.arg.inTokenAddress,
      outTokenAddress: this.arg.outTokenAddress,
      usersCut: this.arg.usersCut,
      gasPrice: gasPrice,
      account: this.userVaultAddress,
    });
   

    logger.info('After accessing tradeResult.data', JSON.stringify(tradeResult.data));

    if (tradeResult.data.data == "0x") {
      // throw Error('Openocean does not support this transaction');
      await this.saveFailedTxn();
      await this.sendRabbitMessage();
      throw {
        type: "TRANSACTION_NOT_SUPPORTED",
        message: `openocean does not support this transaction`,
      };
    }

    let usersResponse = JSON.parse(JSON.stringify(tradeResult.data));
    usersResponse.inAmount = mathOps.toDecimal(
      tradeResult.data.inAmount,
      tradeResult.data.inToken.decimals,
    );
    usersResponse.outAmount = mathOps.toDecimal(
      tradeResult.data.outAmount,
      tradeResult.data.outToken.decimals,
    );
    usersResponse.minOutAmount = mathOps.toDecimal(
      tradeResult.data.minOutAmount,
      tradeResult.data.outToken.decimals,
    );

    return { tradeResult, doApprove, usersResponse };
  };

  execute = async (tenantId, tradeResult, doApprove) => {
    await this.getBaseAssetBalance(this.arg.vaultId);

    if (!doApprove) logger.info("___allowance not needed");
    if (doApprove) {
      const signer = await this.provider.getSigner();
      const signerAddress = await signer.getAddress();
      logger.info("__signerAddress " + signerAddress);
      const contract = new ethers.Contract(
        this.arg.inTokenAddress,
        fireblocksSettings.ooABI,
        signer,
      );
      const balanceRaw = await contract.balanceOf(signerAddress);
      console.log("balance raw is ", balanceRaw);

      const decimals = await contract.decimals();
      console.log("the decimal value is ", decimals);

      const symbol = await contract.symbol();
      console.log("the symbol is ", symbol);

     
      logger.info(
        "__approving " + symbol + "|" + decimals + "|" + this.arg.amount,
      );
     

     

      let approveAmount = ethers.utils.parseUnits(
        this.arg.amount.toString(),
        decimals,
      );

     
      let erc20 = await contract.approve(
        fireblocksSettings.openOceanContractAddress,
        approveAmount,
      );
      const receipt = await erc20.wait();  
    }

    let transactionServiceInstance = new TransactionService(
      this.securityContext,
    );

    let details = {
      from: this.arg.inTokenSymbol,
      to: this.arg.outTokenSymbol,
      outAssetId: this.arg.fireblocksOutAssetId,
      inTokenAmount: this.arg.usersCut,
      totalAmount: this.arg.amount,
      inAssetId: this.arg.fireblocksAssetId,
      amountInUsd: this.arg.amountInUsd,
      outTokenAmount: mathOps.toDecimal(
        tradeResult.data.outAmount,
        tradeResult.data.outToken.decimals,
      ),
      minimumReceived: mathOps.toDecimal(
        tradeResult.data.minOutAmount,
        tradeResult.data.outToken.decimals,
      ),
      inTokenAddress: this.arg.inTokenAddress,
    };

    var gasPriceRaw = await this.provider.getGasPrice();
    var gasPrice = ethers.utils.formatUnits(gasPriceRaw, "gwei");
    gasPrice = gasPrice;
    

    logger.info("before calling the getCryptoTradeSwapQuote")

    tradeResult = await aggregatorService.getCryptoTradeSwapQuote({
      inTokenAddress: this.arg.inTokenAddress,
      outTokenAddress: this.arg.outTokenAddress,
      usersCut: this.arg.usersCut,
      gasPrice: gasPrice,
      account: this.userVaultAddress,
    });

    const tradeTransactionBody = transactionFactory.cryptoTradeContract(
      this.arg.fireblocksAssetId,
      this.arg.vaultId,
      tradeResult.data.data,
      this.arg.inTokenAddress === fireblocksSettings.baseContractAddress
        ? this.arg.usersCut
        : "0",
      this.arg.userId,
      details,
      gasPrice,
      tradeResult.data.estimatedGas * 2,
    );
    logger.info("transcation body", JSON.stringify(tradeTransactionBody));
    const tradeTxnResult = await transactionServiceInstance.create(
      tradeTransactionBody,
      tenantId,
      this.auth0Id,
    );

    return tradeTxnResult;
  };

  getAccountAddress = async (vId, aId) => {
    const depositAddresses = await fireblocks.getDepositAddresses(vId, aId);
    return depositAddresses[0].address;
  };

  getBaseAssetBalance = async (vid) => {
    let vaultAsset = await fireblocks.getVaultAccountAsset(
      vid,
      fireblocksSettings.baseAssetId,
    );
    logger.info(
      `base asset balance of vaultid: ${vid} asset ${fireblocksSettings.baseAssetId}: ${vaultAsset.total}`,
    );
  };

  saveFailedTxn = async () => {
    let resultData = {
      fireblocksTransactionId: "",
      userId: this.arg.userId,
      type: "trade",
      assetSymbol: this.arg.inTokenSymbol,
      CreateDate: new Date(),
      CreatedBy: "",
      TenantId: this.tenantId,
      fromSymbol: this.arg.inTokenSymbol,
      toSymbol: this.arg.outTokenSymbol,
      outAssetId: this.arg.fireblocksOutAssetId,
      outTokenAmount: "",
      minimumReceived: "",
      inTokenAmount: this.arg.usersCut,
      inAssetId: this.arg.fireblocksAssetId,
      amountInUsd: this.arg.amountInUsd,
      totalAmount: this.arg.amount,
      inTokenAddress: "",
      status: "SUBMISSION_FAILED",
    };

    const FireblocksTransactionModel = this.securityContext.getCollection(
      this.tenantId,
      "FireblocksTransactions",
      FireblocksTransactionSchema,
    );

    const fireblocksTransaction = new FireblocksTransactionModel(resultData);
    const txnData = await fireblocksTransaction.save();
  };

  sendRabbitMessage = async () => {
    var rabbitMessage = new TransactionUpdate(
      "--",
      "SUBMISSION_FAILED",
      "SUBMISSION_FAILED",
      this.auth0Id,
      "TRANSACTION_STATUS_UPDATED",
      this.arg.amount,
      this.arg.userId,
      "trade",
    );

    var tokenService = new TokenService(appConfig);

    let token = this.securityContext.extractedToken;

    let ecapToken = await tokenService.getEcapTokenFromAuth0Token(token);

    messageBus.prepareChannel((ch) => {
      messageBus.sendToQueue(
        constants.X4T_CRYPTO_QUEUE,
        ch,
        ecapToken,
        rabbitMessage,
      );
    });
  };
}
module.exports = TradeService;

The function i am using


function roundDownBalance(balance) {
  const roundedBalance = Math.floor(balance * 10 ** 17) / 10 ** 17;
  return roundedBalance;
}

Trade commission function

const getTradeCommission = (arg) => {
  return roundDownBalance((2 / 100) * arg);
};

Users cut function

const getUsersCut = (arg1) => {
  let comission = (getWithdrawCommission(arg1));
  return roundDownBalance(arg1 - comission);
};


do i need to update my  function for this use case 

https://developers.fireblocks.com/reference/balance-decimal-precision

Hi @Shahid do you have a txid for me to investigate?

Here is more information regarding this error you’re experiecing:

INSUFFICIENT_FUNDS

The INSUFFICIENT_FUNDS substatus indicates the transaction failed because the vault account does not have enough funds to fulfill the withdrawal request.

Resolution

This substatus only occurs when using the API. To avoid this issue, refresh your balances or retrieve available vault account balances when creating transactions using the API.

Thanks for your reply. Do I need to round up my values while sending them to fireblocks? when i am calculating the commission and user cut do i need to round up the values? I
Decimal Precision