
Harmony in Progress
January 4, 2024Why Liquidity Pools, Yield Farming, and Real-Time Tracking Matter More Than Ever
April 14, 2025I almost signed a four-line approval once and nearly lost a small position. My gut said, “wait,” and thank goodness I listened. For experienced DeFi users who care about security, simulation isn’t a nice-to-have — it’s the difference between safe composability and handing your funds over to a clever exploit. This piece walks through practical, engineer-friendly ways to think about transaction simulation and how WalletConnect changes the threat model.
Short version: simulate every unfamiliar transaction. Then dig deeper. Don’t trust UI summaries alone.
Transaction simulation is deceptively simple on paper. You run the intended tx against a snapshot of chain state and see what would happen, without broadcasting. Medium complexity: you need to choose the right block state, the right provider, and understand what simulations miss — things like front-running, mempool reorgs, and off-chain oracle updates. Long version: if you want reliable security, you must simulate in layers — a quick local eth_call check, a richer forked-chain replay for internal calls and token flows, and a last-mile check for gas and revert reasons as close to the target RPC as possible, because different nodes have different pending pools and configs.

What transaction simulation actually buys you
Simulation reveals three core things: revert reasons, internal value transfers (token moves, ETH transfers performed by the contract), and side-effect traces (logs, events). Simple eth_call gives you revert checks and return data. A forked-node run (Hardhat/Anvil/Tenderly-style replay) surfaces internal calls and a trace you can audit. The catch: neither captures on-chain timing attacks like MEV frontruns that happen after you send a signed tx into the mempool.
So think in terms of layers. First layer: will this revert? Second layer: what does the contract do if it doesn’t? Third layer: given current mempool and gas, is this likely to be sandwichable or re-org risky? Each layer gives you diminishing returns but also helps you choose mitigants.
How WalletConnect affects the equation
WalletConnect is a session-based bridge between dapps and wallets. It moves signing off the web page and into the user’s device or extension, which is good. But it also expands attack surfaces in subtle ways. For example, a malicious dapp can push a complex transaction request over WalletConnect and expect the wallet to present only a short, human-unfriendly summary. If the wallet doesn’t simulate and decode calldata, the user sees a bland “send” dialog and may sign blindly.
That’s why modern wallets that support WalletConnect need to do two things: decode calldata to human-readable actions, and run at least an eth_call simulation before showing a signing affordance. Even better, run a forked-chain trace so the wallet can show internal token movements and approvals that the dapp might be hiding behind proxy calls.
Tools like Rabby Wallet are built with this mindset — they combine readable transaction previews with on-device simulation and explicit warnings for approval interactions. If you want a wallet that surfaces this level of detail, check it out: https://sites.google.com/rabby-wallet-extension.com/rabby-wallet-official-site/
Practical simulation workflow for advanced users
Okay, here’s a workflow I use and recommend. It’s pragmatic — not perfect, but effective.
- Decode calldata locally. Use ABI or multicall decoders to turn hex into method names and parameters. If you can’t decode, treat it as suspicious.
- Run eth_call with the tx as-is against latest state to detect immediate reverts. This is quick and should be the minimum gate.
- Fork and replay the tx on a local node (Anvil/Hardhat/Tenderly) to inspect traces and internal transfers. This shows token approvals, created contracts, delegatecalls, and surprises.
- Estimate gas and check gas price sensitivity. If a tx needs a wide gas window or sets tip to zero, that can be a red flag for MEV exposure.
- Confirm allowances and approvals — especially ERC-20 approve calls. Prefer permit() where it makes sense, but simulate the actual permit flow too.
- Review the signing request in-wallet: readable intent, explicit token transfers, and approvals. If using WalletConnect, ensure the session scopes are minimal and the dapp origin is expected.
What simulators miss (and how to mitigate)
Simulators can’t fully represent the mempool. That means front-running and sandwich attacks live outside the simulation’s comfort zone. Also, oracles that update off-chain (like TWAPs or Chainlink when keepers call) might flip state between simulation and broadcast. Re-orgs are rare but real: your simulated “success” could be undermined if finality shifts (eh, this is mostly for L2s and congested chains).
So: use higher gas, private relays (Flashbots-style) for high-value ops, and consider submitting through relayers that reduce visible mempool exposure. If the action is time-sensitive or high-value, a private relay or bundle can reduce MEV risk. Not always convenient, but worth considering for big trades.
WalletConnect security knobs
WalletConnect v1 vs v2 — long story short: v2 improves session handling, namespaces, and multiplexing, which means less risk from over-broad sessions. But whatever version you use, pay attention to these security practices:
- Session permission hygiene: limit method namespaces (no personal_sign unless necessary).
- Short-lived sessions: expire or disconnect after use; don’t leave persistent sessions across unknown dapps.
- Prefer hardware wallets for high-value signatures, even when using WalletConnect. The signer should be an air-gapped key when possible.
- Verify the dapp origin: most malicious actors use lookalike domains or social-engineered links. Double-check the URL.
- Use wallets that decode calldata and simulate internally before asking you to sign.
On-chain hygiene checklist for every transaction
Before you press sign, quickly run through this checklist. It’s short, but it saves you from dumb mistakes.
- Decode the calldata — can you explain it in one sentence?
- Are there approvals involved? If yes, is the allowance minimal? Use spender-specific limited allowances.
- Did a simulation show internal token transfers or ETH transfers you didn’t expect?
- Is the gas/tip reasonable relative to current network conditions?
- Is the WalletConnect session scope sane? Does the dapp need to sign on your behalf after this?
- If the action is high-value, consider a private relay or hardware signer.
FAQ
Can eth_call simulations be trusted?
They catch reverts and return values, which is very useful. But they don’t model mempool-based front-running or off-chain oracle updates. Treat eth_call as a first filter, not a guarantee.
Does WalletConnect make me less secure?
Not inherently. It moves signing to a trusted client instead of the web page. But it also depends on the wallet implementation: if the wallet shows only terse confirmations without simulation and decoding, you’re at risk. Use wallets that simulate transactions and clearly display intent.
What’s the fastest way to check approvals?
Decode the transaction and look for approve or increaseAllowance calls. If you’re uncertain, simulate and inspect token flows on a forked node; it will show exactly which allowances change.
