A user connects their wallet to a decentralized exchange, approves what appears to be a routine token swap, and encounters an error message: „Transaction simulation failed.“ The interface offers no detail about why. Did the contract reject the transaction? Is liquidity insufficient? Has the user been targeted by a sandwich attack? Without understanding what simulation actually does, the user either retries repeatedly, increasing gas costs, or abandons the transaction entirely. The distinction matters because transaction simulation is one of the few points where a self-custodial wallet can warn about outcomes before broadcasting to the blockchain.
Rabby Wallet’s transaction simulation feature operates differently from older wallets that simply display raw transaction data and hope users understand the implications. By executing transactions in a local simulation environment before submission, Rabby can identify contracts that fail, authorization issues, slippage violations, and other outcomes. When a simulation fails, it is a signal that something in the contract interaction or state is inconsistent with what the user intends. Understanding why that happens, and what to do about it, separates wallet users who can troubleshoot from those who treat the wallet as opaque.
How transaction simulation works and what it prevents
Transaction simulation is a computational preview. Rather than broadcasting a transaction directly to the blockchain, Rabby executes it against a copy of the current blockchain state held locally. The simulation runs the contract code, checks authorization rules, verifies that accounts have sufficient balances, and confirms that all operations complete without reverting. If any step fails, the simulation stops and reports the error. The user sees this result before paying gas and before the transaction becomes irreversible on the blockchain.
This approach catches several categories of problems that would otherwise produce wasted gas and failed transactions. A contract might require approval of a token before a swap or deposit can proceed; if the approval has expired or is insufficient, simulation detects it. A liquidity pool might be temporarily empty or under maintenance; simulation shows that condition. A user might attempt to withdraw more assets than they have deposited; the simulation fails. A decentralized application might have paused withdrawals due to a security incident; simulation reveals the pause state. Without simulation, all of these scenarios result in transactions that appear to execute but actually revert, costing gas without moving assets.
The feature also mitigates certain attack surfaces. If a smart contract has been compromised or contains a hidden vulnerability, simulation may show unexpected behavior: unauthorized transfers, token burning, or state changes that the user did not intend. Rabby cannot guarantee that every malicious contract is caught; sophisticated attacks may succeed even in simulation. But the simulation layer provides a defense that other wallets that simply display a contract address and function name do not offer. It shifts the burden from „trust the contract“ to „observe what the contract does.“
Simulation is therefore a control mechanism, not an infallible filter. A contract can pass simulation and still behave unexpectedly once broadcast because blockchain state changed between simulation and submission, or because a feature of the actual network differs from the simulation environment. But the default position—catching problems before gas is spent—aligns with the interests of a self-custodial user who pays transaction fees directly and cannot reverse a failed block.
Common reasons simulation fails and what each one means
Insufficient balance is the most straightforward failure. A user attempts to send more tokens or native currency than their account holds. The simulation checks the account state, finds the balance insufficient, and stops. The solution is to reduce the amount or acquire more of the asset. This is simple in principle but sometimes confusing in practice: a user may hold token A but try to swap it for token B using a route that requires intermediate conversions, and the fee for each conversion can consume more balance than expected. Simulation exposes that discrepancy.
Missing or insufficient approval occurs when a smart contract requires explicit permission to transfer a user’s tokens, but that permission was never granted or has expired. Decentralized exchanges typically use the ERC-20 approve function to let a contract transfer tokens on a user’s behalf. If the approved amount is less than the transaction amount, or if no approval has been issued, the simulation fails at the approve step. The remedy involves issuing an approval first—sometimes a separate transaction—and then retrying the original swap. Some newer protocols use permit functions to bundle approval and transfer in one step, reducing this friction, but many established contracts still require sequential transactions.
Contract state constraints include pauses, halts, and role-based restrictions. A decentralized application may pause deposits temporarily during a security audit or maintenance window. A farming contract might stop accepting new positions once it reaches a cap. An NFT marketplace might restrict listings to whitelisted users or authenticated accounts. These constraints are encoded in contract functions as require statements. When simulation executes the function and checks whether the constraint is met, it fails if the condition is false. The user cannot bypass this; the only remedy is to wait for the pause to lift or for their account status to change.
Slippage and price movement failures are more subtle. A user initiates a token swap with a specified minimum output; they are willing to accept a rate of 1 token A for 1.05 token B, but no worse. If the blockchain state changes between when the simulation ran and when the transaction actually executes, the available rate might shift to 1 for 0.98. The swap would revert because the actual output would violate the minimum. Simulation detects this potential problem if it can simulate at a slightly worse rate, but it cannot predict future price movements. The practical response is to set a less aggressive minimum output, accept more slippage, or use a more direct route with less intermediate conversion steps.
Network and contract errors also cause simulation failures. If a required oracle is unavailable, a cross-chain bridge is down, or a liquidity pool is in an inconsistent state, simulation may fail. These are usually temporary. The appropriate response is to wait and retry rather than modifying the transaction parameters. Retrying too quickly may produce the same error; spacing out retry attempts gives the network or contract time to recover.
Why simulation environment and mainnet state are not identical
Rabby’s simulation runs against a local copy of blockchain state that is synchronized with the network. But synchronization is not instantaneous, and certain network conditions cannot be fully replicated locally. A transaction that passes simulation may still fail on-chain because the real state changed between the moment of simulation and the moment the transaction was included in a block.
This is particularly acute in volatile or high-traffic conditions. A decentralized exchange might have had sufficient liquidity when the user simulated but experienced large withdrawals in the seconds before the transaction was mined. A staking contract might have accumulated more deposits, triggering a cap that was not yet active during simulation. A token might have been paused or blacklisted on the actual network in a way that was not reflected in the local state copy. The simulation environment is therefore a useful but incomplete predictor of on-chain behavior.
Mempool activity also introduces divergence. Rabby simulates what will happen if the transaction executes immediately. But the actual transaction may sit in the mempool for several blocks, during which other transactions execute, state changes accumulate, and prices move. A sandwich attack amplifies this risk: a malicious participant can insert their own transactions before and after the user’s transaction in the same block, extracting value through price manipulation. Simulation does not account for this because it cannot predict which other transactions will be included in the same block.
The implication is that a successful simulation is necessary but not sufficient. It eliminates obvious contract failures and authorization issues. It does not guarantee that the transaction will succeed if conditions are volatile, if the route is illiquid, or if the user is interacting with a newly deployed or untested contract. Users interacting with multiple EVM chains including Ethereum, Base, Arbitrum, Optimism, and Polygon should be aware that each network has different block times, fee structures, and congestion patterns, which affect how quickly simulation results become stale.
How to interpret simulation errors and adjust your transaction
When simulation fails, the error message often includes a reason. Parsing that message is the first step. If it says „ERC20: insufficient allowance,“ the contract needs approval. If it says „Insufficient balance,“ check your token holdings. If it contains a revert reason like „Swap amount too small“ or „Slippage exceeded,“ the transaction parameters need adjustment. If the message is cryptic or incomplete, the error may originate from an external contract that the transaction calls, and troubleshooting requires understanding the transaction’s flow.
Some errors are actionable by the user. Set a higher slippage tolerance, issue an approval first, or reduce the transaction size. Others are environmental: the smart contract is paused, the network is congested, or liquidity is temporarily depleted. In these cases, the correct response is to wait and retry later rather than repeatedly attempting the same transaction with minor variations. Each retry costs gas, and persistent failures signal a condition that will not resolve by tweaking parameters.
For complex transactions involving multiple steps or bridging between EVM chains, breaking the transaction into smaller components can isolate which step is failing. Instead of executing an atomic swap that includes a bridge and a deposit, execute the swap first, confirm the received tokens, then execute the deposit. This approach costs more in total fees because separate transactions pay separate gas costs, but it provides clarity about where failures originate and allows recovery if one step succeeds and another fails.
Users installing the rabby wallet extension or mobile application should also check that they are connected to the intended network. Rabby includes automatic network detection, but if a user manually switched networks or is interacting with a decentralized application that specifies a different network, the transaction might be correctly formatted for one chain but intended for another. Verifying the network name and chain ID in the wallet interface before confirming prevents transactions that would otherwise succeed but on the wrong blockchain.
Preventing simulation failures through transaction design
The first prevention principle is to reduce transaction complexity. Simple swaps on a single blockchain, direct token transfers, and straightforward contract interactions are less likely to fail than multi-step transactions that bridge networks, use nested external calls, or depend on oracle data. When complexity is necessary, test smaller amounts first. A user planning to deposit $10,000 in a new protocol should send $100 as a test, observe that the transaction succeeds and the funds appear in the expected account, then move the larger amount.
The second principle is to manage approval flows separately. Rather than attempting to combine an approval and a transaction in the same flow, approve the contract explicitly, confirm the approval in a block, then execute the transaction. This adds a delay and costs more in total gas, but it isolates the approval step where many contracts have state requirements or limitations. Newer protocols offering permit-style approval bundled with transfer reduce this friction, but most established decentralized exchanges and protocols still require sequential steps.
The third principle is to set realistic slippage and price parameters. Simulation failures related to slippage often reflect the user setting expectations that are too tight. A liquidity pool’s exchange rate can shift by several percent during a large transaction or in volatile market conditions. Setting a minimum output below the maximum possible loss the user can tolerate reduces failures without exposing the user to unacceptable price movement. Tools that quote multiple routes and allow manual route selection can help find more stable swap paths.
The fourth principle is to monitor network conditions before submitting large transactions. High gas fees, network congestion, and low validator availability all increase the risk that a transaction will sit in the mempool for extended blocks, making simulation results stale. Checking blockchain explorers for average block times, gas price trends, and recent failed transactions on the target contract can inform whether the moment is appropriate for the transaction or whether waiting might be prudent.
When simulation succeeds but the transaction still fails
A transaction that passes simulation can still fail on-chain if network state changed after simulation. The most common scenario is a reorg on the blockchain: the block containing the user’s transaction is orphaned, and when the transaction is re-mined in a different block, the state has shifted enough to cause a failure. Another scenario is mempool volatility: competing transactions execute, depleting liquidity or triggering state changes faster than the user anticipated. A third scenario is contract behavior that cannot be fully simulated, such as contracts that depend on external data feeds that were interrupted or updated during the delay between simulation and execution.
When this occurs, the transaction is confirmed on-chain as failed; the user can see the failure on a blockchain explorer, and it has cost gas. The funds involved in the transaction were not transferred, but the gas expense cannot be recovered. The appropriate next step is to analyze the on-chain failure reason, adjust the transaction parameters if needed, and retry with a lower gas price or at a different time when conditions may be more favorable. Blaming the wallet is tempting, but the wallet can only simulate; it cannot control post-submission state changes.
For hardware wallet users or those employing multi-signature schemes, verification of the transaction parameters becomes more critical because each step involves additional confirmation steps. A failed transaction through a hardware wallet requires physical confirmation to retry, adding a real cost to experimentation. These users should verify simulation results extra carefully and be conservative about slippage settings and complex routes.
Documentation and error messages in the blockchain explorer often provide the actual revert reason for failed transactions. Looking up a failed transaction’s hash on an EVM block explorer and reading the revert data can clarify whether the failure was a state change, authorization issue, or contract bug. This information informs whether retrying the same transaction is likely to work or whether a parameter adjustment or route change is necessary.
Simulation as a security and usability control
Transaction simulation is fundamentally a risk-reduction mechanism. It replaces the older model where wallets displayed raw contract data and users were expected to understand what would happen by reading contract addresses and function names. Most users cannot and should not be expected to understand contract bytecode or low-level transaction encoding. Simulation translates contract behavior into concrete outcomes: „This transaction will transfer 10 USDC from your account to the contract“ or „This transaction will revert because you do not have approval.“
The simulation feature also deters certain social engineering attacks. A user might be tricked into clicking a malicious link that attempts to execute a contract function designed to drain their account. If that contract function would transfer all of their funds or approve a massive token transfer, simulation will reveal the impact in concrete terms. The user can then decide whether to proceed or reject the transaction. This is still not foolproof; a user who explicitly approves a drain under false pretenses is not protected by simulation. But the layer of explicit feedback about outcomes provides a speed bump that encourages users to pause and verify.
For traders and DeFi users who interact with multiple EVM chains regularly, simulation reduces operational mistakes. A user switching between Ethereum, Arbitrum, and Polygon might accidentally attempt a transaction on the wrong network. Automatic network detection helps, but simulation provides another check: if the transaction fails because a contract does not exist on the selected network, or a token balance is zero because it has not been bridged to that network, simulation will surface that issue before gas is spent.
Designing your transaction strategy around simulation results
A professional approach to wallet transactions involves treating simulation results as critical information rather than obstacles to push past. If a simulation fails, the failure message is diagnostic data. Decoding that data—identifying what constraint is not met, what authorization is missing, or what state condition is violated—allows targeted fixes rather than blind retries.
For complex transactions, separating concerns helps. Approve before swapping. Swap before depositing. Bridge before trading. Each intermediate step can be verified independently, and if one fails, the rest of the plan can be adjusted without losing already-completed steps. This approach costs more in total gas but eliminates cascading failures where a later step fails because an earlier step did not complete as expected.
For high-value transactions, using a hardware wallet or smart contract interaction through a test network first can provide additional verification. Most EVM-compatible chains include testnet versions where transactions cost nothing and do not alter real assets. Testing a new protocol interaction on testnet, confirming that simulation succeeds and the transaction executes as expected, then moving to mainnet with the same parameters reduces the risk of surprises. This is a best practice for DeFi users but is often skipped in the interest of speed.
The final consideration is timing. Transaction success often depends on network conditions, block availability, and recent state changes. Submitting large transactions or complex contract interactions during off-peak hours, when gas prices are lower and blocks are less congested, improves the chances that simulation results remain valid through execution. Conversely, submitting during peak volatility or network stress increases the risk that the state will shift enough to invalidate simulation results.
Frequently asked questions
Why does my transaction pass simulation but fail on-chain?
Simulation runs against a snapshot of the blockchain at the moment of checking. Between simulation and block inclusion, other transactions may execute, state may change, liquidity may shift, or prices may move. If the actual state differs enough from the simulated state, the transaction can revert even though simulation indicated success. This is especially common during high volatility or network congestion. Adjusting slippage tolerance, reducing transaction size, or retrying at a less busy time can help.
What does „insufficient allowance“ mean and how do I fix it?
The contract requires permission to transfer tokens on your behalf, but that permission is either missing or insufficient for the amount you are attempting to transfer. Issue an approval transaction first, specifying the amount or an unlimited allowance, wait for it to be included in a block, then retry the original transaction. Different contracts have different approval requirements and expiry conditions.
Can I prevent simulation failures altogether?
No, but you can minimize them. Break complex transactions into smaller steps, test new protocols with small amounts first, check network conditions before submitting large transactions, and set realistic slippage and price parameters. Use separate approval transactions rather than attempting bundled approval and execution. Simulation failures that originate from contract state constraints or network conditions cannot be entirely avoided, but careful transaction design reduces the frequency.
