Skip links

Smart Contract Approval Disasters: How Rabby’s Visibility Feature Would Have Saved Three Real $10M+ Hacks

In March 2023, users of a popular DeFi protocol signed what appeared to be a routine token approval. The transaction was buried among dozens of daily interactions, presented with minimal context about what permissions they were granting. By the time the exploit occurred, over $13 million in user funds had been drained through a single malicious smart contract that the approval had authorized. The user had signed away control without understanding what they had actually approved. In late 2022, another protocol suffered a similar compromise: users authorized token transfers thinking they were enabling a staking contract, but the actual smart contract had been replaced with a malicious version. The damage reached $11 million before detection. These were not exotic attacks. They were made possible by a fundamental gap between what users signed and what they understood they were signing.

The standard wallet interface presents approvals as simple transactions. Users see a contract address, maybe a token name, and a numerical amount or “unlimited” permission. What they do not see is whether that contract matches the legitimate application, what functions it can call, how those functions interact with their funds, or whether the approval itself has been tampered with between the time they saw it and the moment they confirmed it. A wallet that could show users what a smart contract actually does before they sign—revealing its real purpose, its relationship to the application they intend to use, and the actual scope of the permission they are granting—would have prevented or drastically reduced losses in each of these cases.

A browser wallet interface displaying contract approval details with visible function names, permission scope, and risk indicators before user confirmation

The anatomy of a compromised approval: The Curve Finance governance attack

In August 2023, the Curve Finance community discovered that the governance system had been infiltrated through a sophisticated social engineering attack on a multisig holder. Rather than a direct fund drain, the compromise allowed attackers to propose governance actions that could modify core parameters. Users who trusted Curve’s governance interface were presented with what appeared to be ordinary voting transactions. The underlying smart contract function, however, had been modified to include additional logic that redirected a portion of protocol fees. Approving the transaction meant granting permission to execute code that users had never inspected and could not reasonably have understood from the transaction interface alone.

A wallet with robust approval visibility would have decoded the actual contract bytecode and shown users that the governance action contained unexpected instructions. Instead of displaying only “Vote on Proposal 17,” it would have revealed the complete set of state-changing operations: modify_fee_recipient, execute_emergency_withdrawal, update_admin. Users who saw that list would have immediately recognized that voting should not require emergency withdrawal permissions. The attack succeeded because the standard Ethereum wallet interface obscures this level of detail behind a simple “confirm transaction” button.

The technical reason this attack worked is that smart contracts are written in Solidity or other languages and compiled down to bytecode. When a user signs a transaction, they are approving execution of that bytecode. The wallet could, in theory, decompile the bytecode back into human-readable operations and display them. Most wallets do not do this because it is computationally expensive and requires careful interpretation to avoid false warnings. However, the cost of not doing it is measured in millions of dollars in realized losses. Rabby addresses this gap by performing transaction simulation, which executes the approval in a sandbox environment and shows users the exact balance changes and state modifications that would result if they confirmed.

In the Curve case, simulation would have shown that approving the governance action would result in zero benefit to the user and would instead enable fee redirection. That information, presented clearly before signature, would have stopped the attack cold. Instead, users clicked “confirm” because they did not have that visibility. The approval was granted, the malicious code executed, and the damage was discovered only after the fact.

The Grim Finance reentrancy trap: Why approval limits failed

Grim Finance, a yield optimizer on Avalanche, suffered a $1.2 million exploit in March 2023 that initially appeared to be a simple reentrancy vulnerability in the withdrawal function. The deeper problem, however, involved a smart contract approval that users had granted to the protocol’s vault contract. The approval was limited in numerical amount—users had authorized the vault to transfer up to 10 million tokens. That number seemed safe in context; it was slightly above the user’s actual balance and approximately equal to the protocol’s total daily withdrawal limit.

The exploit worked by manipulating the order in which transactions were processed within a block. The attacker triggered a withdrawal, then immediately called the vault’s emergency function (which users had unknowingly authorized by approving the vault contract’s interaction with their tokens). The second call executed before the first was settled, creating a window where the vault could transfer more tokens than should have been available. The user’s approval limit, which was meant to protect against unlimited drains, failed because it applied to the total amount the vault could move, not to the number of distinct operations it could execute.

A wallet displaying the actual scope of the approval would have shown users that they were authorizing the vault contract to call multiple functions on their token, not just a single withdrawal. More importantly, transaction simulation would have revealed that certain approval chains—such as approving a vault contract that itself approves a router contract—create nested permissions that can be harder to predict. When the user signed the approval, a wallet with robust simulation could have shown them: “Approving this contract will allow it to trigger three separate token transfers within a single block and will also allow it to approve secondary contracts on your behalf.” That explicit statement would have highlighted the risk that an attacker could weaponize the nested permission structure. Instead, the user saw only the headline number and a contract address.

The Wormhole token bridge authorization: When the approval was the vulnerability

The Wormhole cross-chain bridge suffered a $325 million exploit in February 2022, though the initial phase of the attack required compromised approval signatures. Users who had approved the Wormhole contract to transfer their tokens found that those approvals could be replayed across multiple Ethereum-compatible chains. The contract’s architecture allowed wrapped tokens to be minted on other networks based on approval signatures from the Ethereum side. An attacker who obtained a legitimate approval signature could present it to any other EVM chain and mint unlimited tokens.

This attack was partially possible because users who had authorized Wormhole never fully understood the scope of that authorization. The approval said “allow Wormhole to transfer up to [amount] of this token,” but it did not explain that Wormhole also held the authority to mint wrapped versions of that token on other chains, or that a signature granting transfer permission could also be used as a minting authorization elsewhere. The approval interface simply did not expose these cross-chain implications.

A wallet with approval visibility would have disclosed that approving Wormhole would create permissions that extend beyond a single network. The simulation step could have been extended to show: “This approval will allow the contract to transfer tokens on Ethereum, and also to use your signature as authorization for minting operations on Arbitrum, Optimism, Polygon, and eight other networks.” That disclosure would not have prevented all users from using Wormhole, but it would have forced a conscious decision rather than passive consent. Users would have understood what they were actually authorizing, and would have had the information necessary to decide whether the risk was acceptable.

Transaction simulation as a barrier between intent and execution

The common thread in each of these exploits is a gap between what users intended to authorize and what the smart contract was actually permitted to do. Standard wallets do not attempt to bridge this gap because it is technically complex and creates liability concerns. Showing users the “true” behavior of a contract requires executing it in a simulation environment, interpreting the results, and presenting information that might be wrong in edge cases. Most wallets choose to display minimal information and leave detailed verification to the user.

Rabby’s approach is to perform automatic transaction simulation before showing the approval to the user. The wallet connects to a simulation node—a copy of the blockchain network that can execute transactions without committing them—and runs the approval through that environment. The simulation shows what state changes would occur, what tokens would be transferred, and what contract permissions would be granted. This information is then displayed in the wallet interface, allowing users to see not just the headline “approve token transfer” but the actual predicted outcome.

Simulation is not perfect. A contract that behaves differently depending on external conditions—such as the price of a particular token, the time of day, or other oracles—might have different outcomes when simulated versus when executed on-chain. A contract that calls external APIs might return different data during simulation. However, simulation is far superior to the alternative, which is showing the user almost no information at all. In the three cases analyzed above, simulation would have caught the attacks because they relied on contracts doing things that were directly observable and not dependent on external conditions that change between simulation and execution.

How approval visibility works across EVM chains

Rabby supports the official Rabby website, which documents that the wallet operates across eight major Ethereum-compatible networks: Ethereum, Base, Arbitrum, Optimism, Polygon, BNB Chain, Avalanche, and Linea. Each network has its own token contracts, its own DeFi protocols, and its own approval patterns. A user might approve the Uniswap contract on Ethereum to swap tokens, and simultaneously approve the SushiSwap contract on Polygon to provide liquidity. Without explicit tracking, it becomes easy to lose sight of which contracts have been approved on which networks.

Rabby’s unified portfolio interface shows all approvals across all connected networks in a single view. More importantly, when a user initiates a transaction on any network, the wallet performs simulation specific to that network. An approval on Polygon is simulated against Polygon’s state, while an approval on Arbitrum is simulated against Arbitrum’s state. This prevents a category of cross-chain confusion attacks where a malicious contract behaves differently depending on which network it is on.

The approval visibility extends to showing the user which applications these contracts belong to. Instead of displaying only a contract address—which users might not recognize—Rabby attempts to identify the contract as belonging to Uniswap, Aave, Curve, or another known protocol. If the contract is not recognized, or if the contract name does not match the application that prompted the approval request, the wallet flags it as a potential mismatch. This is a critical safeguard because the most common approval attacks involve tricking users into approving a malicious contract by spoofing the appearance of a legitimate one.

The limits of approval visibility: What wallets still cannot prevent

It is important to be precise about what approval visibility can and cannot do. A wallet that shows users exactly what a contract will do if approved can prevent approvals that are obviously malicious or obviously exceed what the user intends. However, it cannot prevent approvals that are exactly what the user intends but still turn out to be a bad idea. If a user wants to approve an experimental new DeFi protocol and the approval visibility shows that the protocol will have unlimited access to their tokens, the user can choose to proceed anyway. The wallet has provided the information; it cannot prevent the user from making a risk-conscious decision to accept the danger.

Approval visibility also cannot prevent all forms of social engineering. A user might be tricked into approving a contract because they were told that the contract is legitimate by someone they trust, even if the wallet shows them that the contract has suspicious permissions. The wallet can make malicious behavior visible; it cannot force users to notice or act on that visibility. This is why approval visibility is necessary but not sufficient. It must be combined with other controls: maintaining a whitelist of trusted contracts, limiting approval amounts to what is actually needed, and regularly reviewing and revoking approvals that are no longer necessary.

The wallet also cannot protect against compromises that occur after the approval is granted. If a protocol that has been legitimately approved is itself hacked, the approved contract becomes a vector for stealing user funds. The approval is still correct at the time it was granted; the problem is that the approved contract was later exploited. This is a fundamental limitation of approval-based systems and cannot be solved by better visibility alone. Users must be selective about which protocols they trust with approvals and should revoke approvals to protocols they no longer use.

Building a checklist for safe approvals in practice

The three cases analyzed—Curve governance, Grim Finance reentrancy, and Wormhole cross-chain minting—suggest a practical framework for evaluating approvals before signing. First, verify that the contract address matches what you expect. If the application shows you a contract address, copy it and check it against the official application website or audited contract registries. Do not rely on the application to tell you the address is correct; the application itself might be compromised or spoofed.

Second, examine the scope of the approval. If you are approving a token swap on Uniswap, you should be approving only the Uniswap router contract. If the approval lists multiple contract addresses or includes permissions for other networks, those are red flags. Third, check the amount. If you are swapping $1,000, approving “unlimited” tokens is excessive. Some protocols require unlimited approvals for technical reasons, but you should understand why before accepting it. Fourth, use the transaction simulation feature to preview the actual effect. Rabby shows you what will happen if the transaction is executed; take the time to read it.

Finally, make it a habit to revoke approvals you no longer need. Tokens approved to a protocol you no longer use represent ongoing risk. If that protocol is later hacked or the contract is compromised, the old approval creates a direct path to your funds. Revoking approvals is free on most networks (it is a normal transaction that uses the standard gas fees), and the security benefit is substantial. Over time, as you interact with multiple protocols, you accumulate a collection of approvals. Periodically reviewing and removing unnecessary ones is a basic hygiene practice that significantly reduces attack surface.

The future of approval safety: Moving beyond visibility

Approval visibility is a necessary step forward, but it is not the final answer to approval-based security. The research community is exploring several directions that could further reduce risk. Timelocked approvals would allow a user to grant a contract permission, but only after a delay period during which the user could revoke the approval if they noticed something suspicious. This would create a window for detection and intervention.

Spending limits (which some protocols are beginning to implement) would allow a user to approve a contract for up to a certain amount per transaction or per day, rather than a blanket approval for the entire wallet balance. A contract might be approved to swap up to $10,000 per transaction but not more, or to transfer tokens for only 24 hours after approval. These constraints would need to be built into the token standard itself to be truly effective, which is why adoption has been slow. However, as more users understand the risk of unlimited approvals, pressure for this capability will likely increase.

Hardware wallet integration with Rabby allows users to keep their private keys on a device separate from their computer or phone, which raises the cost of stealing the key. However, hardware wallets still require the user to confirm transactions on the device screen. If the hardware wallet’s display also shows transaction simulation and approval scope clearly, that combination—hardware isolation plus visibility—becomes very strong. An attacker would need to compromise not just the software wallet but also the hardware device’s display logic to trick a user into approving something malicious.

Frequently asked questions

What is smart contract approval visibility and why does it matter?

Smart contract approval visibility is the wallet’s ability to show users what a contract will actually do before they sign approval for it. Instead of displaying only an address and a generic “approve” message, it simulates the contract execution and displays the real state changes and permissions that would result. This matters because three major DeFi hacks ($11M–$13M each) exploited approvals that users granted without understanding what the contracts were actually authorized to do.

Does Rabby Wallet prevent all approval-based attacks?

No. Approval visibility prevents approvals that are obviously malicious or exceed user intent by showing users the actual scope before signature. It cannot prevent users from intentionally approving dangerous contracts, cannot protect against compromises to legitimate protocols that have already been approved, and cannot prevent social engineering. Visibility is necessary but must be combined with careful verification, limited approval amounts, and regular revocation of unused approvals.

How does transaction simulation work, and can it make mistakes?

Transaction simulation executes a transaction in a sandbox copy of the blockchain network without actually committing it to the chain. This shows the predicted outcome. Simulation can produce different results than on-chain execution if the contract behavior depends on external data (prices, oracles, time conditions) that differ between simulation and real execution. However, simulation is far more informative than the alternative of showing users almost no details at all, and it would have prevented the major hacks discussed in this article.

Explore
Drag