Skip to main content
Let’s take a look at a real-world scenario where batching transactions streamlines interactions while also helping prevent malicious activity.

DeFi Vault Deployment

When deploying a new customer vault on Uniswap V4, you need to execute three critical operations atomically:
  1. Initialize a new pool for the customer tokens
  2. Update your vault/module to use that new pool
  3. Execute a rebalance to deposit the tokens
The challenge is that these operations must happen atomically to prevent front-running attacks where bots move pool prices to unfavorable positions during the time gap between operations. Using a smart wallet with batched transactions ensures all operations execute in a single atomic transaction with the correct msg.sender. Here’s a quick guide on how to batch transactions using Gelato Smart Wallets for such use cases.

Batching Transactions

You can batch multiple transactions to be sent on-chain at once by adding them to the calls array:
 const result = await smartWalletClient.execute({
 payment: sponsored(),
 calls: [
   // 1. Initialize the vault with pool parameters
   {
     to: vaultManager,
     data: encodeFunctionData({
       abi: vaultManagerAbi,
       functionName: "initialize",
       args: [
         init0, // Initial amount for token0
         init1, // Initial amount for token1
         isInversed, // Pool direction
         poolKey, // Pool configuration
         oracle, // Oracle wrapper address
         maxSlippage, // Maximum slippage tolerance
         metaVault // Meta vault address
       ]
     }),
     value: 0n
   },
   // 2. Set the pool configuration and liquidity ranges
   {
     to: vaultManager,
     data: encodeFunctionData({
       abi: vaultManagerAbi,
       functionName: "setPool", 
       args: [
         poolKey, // Pool key configuration
         liquidityRanges, // Liquidity range parameters
         swapPayload, // Swap configuration
         minBurn0, // Minimum burn amount for token0
         minBurn1, // Minimum burn amount for token1
         minDeposit0, // Minimum deposit amount for token0
         minDeposit1 // Minimum deposit amount for token1
       ]
     }),
     value: 0n
   },
   // 3. Execute rebalance to deposit liquidity
   {
     to: vaultManager,
     data: encodeFunctionData({
       abi: vaultManagerAbi,
       functionName: "rebalance",
       args: [
         liquidityRanges, // Liquidity range parameters
         swapPayload, // Swap configuration
         minBurn0, // Minimum burn amount for token0
         minBurn1, // Minimum burn amount for token1
         minDeposit0, // Minimum deposit amount for token0
         minDeposit1 // Minimum deposit amount for token1
       ]
     }),
     value: 0n
   }
 ]
});
This approach prevents front-running by ensuring all operations execute atomically, eliminating the time gap where bots could manipulate pool prices.

Summary

You get the security of atomic execution and the efficiency of smart wallets — without the complexity of managing multiple transactions or the risk of front-running attacks.