Key Takeaways
An approval transaction is the one moment in a crypto interaction where a wallet holder gets to stop and ask, in plain terms, "what exactly am I about to give this address the right to do?" Most approvals are routine and harmless — a decentralized exchange needs permission to move a token during a swap, a marketplace needs permission to move an NFT once it sells. But the exact same mechanism that makes those legitimate flows work is what every approval-based drain relies on, and the request itself rarely announces which category it falls into. It takes reading the details.
Direct answer: Before confirming any approval or permit request, check five things: whether the spender address is one you actually recognize for this specific action, whether the requested amount is unlimited when it doesn't need to be, whether the function is setApprovalForAll (a blanket grant over an entire NFT collection, not one item), whether you deliberately navigated to this site or just landed on it, and whether your wallet's transaction simulation shows an outcome that matches what you expected. Any one of these failing is a reason to stop and investigate before signing.
- The spender address is the single most important field in any approval request — it names exactly who is being granted permission, and it should always match what the action you're taking actually requires.
- An unlimited (max uint256) approval amount isn't automatically malicious, but requesting it for an action that plainly doesn't need repeated access is a real warning sign.
- setApprovalForAll grants an operator transfer rights over an entire NFT collection, not a single token, and is the mechanism behind a disproportionate share of major NFT-holder drains.
- A polished, professional-looking site provides zero information about whether the approval it's requesting is safe — visual design and smart contract logic are completely unrelated.
- Wallet simulation tools that translate a raw request into plain language, such as "this grants unlimited transfer rights over your entire collection to 0xABC...," turn blind signing into an informed decision.
- Approving out of habit or "convenience" on a marketplace, without checking the requested scope, is one of the most common ways experienced users still get drained.
What an Approval Transaction Actually Grants
Before getting into red flags, it's worth being precise about what an approval transaction is, because the word "approval" gets used loosely and that looseness is part of what scammers exploit. In the ERC-20 token standard, an approval is a specific on-chain call to a token contract's approve function, naming a spender address and an amount, that grants the spender the right to move up to that amount of your tokens on your behalf, whenever the spender's own contract logic decides to call it. It is not a transfer. Nothing moves the moment you approve. What moves is a standing permission — a door that stays unlocked until you either use it up, revoke it, or it never gets used at all.
This design exists for a completely legitimate reason. A decentralized exchange can't move your USDC into a swap unless you've first told the USDC contract that the exchange's router is allowed to do so; without an approval step, every DeFi protocol would need to hold your funds directly, which would be far riskier, not safer. So the approval pattern itself is not the problem. The problem is that the same mechanism, requested by an address you don't recognize, for an amount larger than the action requires, on a site you have no real reason to trust, is indistinguishable at the wallet-prompt level from the legitimate version unless you specifically look for the differences.
Permit signatures — sometimes shown as "permit," "Permit2," or similar labels — accomplish functionally the same outcome through a different mechanism: rather than an on-chain approve transaction, they use an off-chain signed message that a contract can later redeem to grant itself the same kind of spending permission. Because a permit is just a signature rather than a transaction, it typically costs no gas and can feel even more like a low-stakes formality than an approval transaction does, which is exactly why it deserves the same level of scrutiny, not less. Both mechanisms — on-chain approvals and off-chain permits — grant the same category of standing permission, and both are worth evaluating with the same checklist.
The Red-Flag Checklist
Every approval or permit request, regardless of what site presents it or how it's worded, can be evaluated against the same five questions. None of them require deep technical knowledge — they require slowing down for the ten or fifteen seconds it takes to actually read the prompt instead of clicking through it.
1. Is the spender address one you recognize and expect for this specific action?
Every approval names a spender: the address being granted permission. This is the single most load-bearing field in the entire request, because it answers the question "who, exactly, is getting access?" A swap on a known decentralized exchange should request an approval for that exchange's own router contract, a documented, publicly verifiable address. A marketplace listing should request an approval for that marketplace's own listing or transfer-proxy contract. If the spender address doesn't match what the site's own documentation, a trusted aggregator, or a block explorer shows as the legitimate contract for that action, that mismatch is a red flag on its own, independent of anything else about the request.
2. Is the requested amount unlimited when the action doesn't obviously require that?
An approval amount of the maximum possible value a token contract can represent — commonly called "unlimited" or max uint256 — grants a spender the right to move essentially any amount of that token, not just what's needed for the immediate action. Some legitimate protocols request this by default purely to save users from paying gas for a new approval every single time they interact with the protocol again. That convenience tradeoff is a real, defensible design choice some users are comfortable with and others aren't. But an unlimited request for something that is obviously a one-time action — approving a specific NFT sale, making a single token transfer — doesn't need repeated access at all, and requesting it anyway is worth noticing, especially from a spender you don't already trust.
3. Does the request use setApprovalForAll?
This one deserves its own section below, but as a checklist item: any request that surfaces the function name setApprovalForAll, or that a wallet's plain-language summary describes as granting access to an entire collection rather than one item, should be treated as categorically higher-risk than a normal token approval, because of what it grants and what it's historically been used to do.
4. Are you on a site you deliberately navigated to, or one you just arrived at?
Context matters as much as the technical content of the request. An approval prompt that appears on a site you typed in yourself, bookmarked, or reached through a link you independently verified carries a different risk profile than one that appears after clicking a link from an unsolicited direct message, a Discord announcement you can't verify came from an actual moderator, or a search ad. The request itself might look identical either way — the difference is entirely in how much reason you have to trust the site presenting it, and that context should directly affect how much scrutiny the request gets before you sign.
5. Does your wallet's simulation show an outcome that matches what you expected?
If your wallet or a connected extension offers transaction simulation, it exists specifically to answer this question: given everything in the request, what will actually happen if you sign it? A simulation that confirms an outcome matching your expectation — "this will list your NFT for the price you set" — is reassuring. A simulation that shows something you didn't expect — "this will grant unlimited transfer rights to an address you've never interacted with" — is the clearest, plainest-language version of a red flag this entire checklist is built to surface, and it should stop you from signing regardless of how legitimate everything else about the site looked.
Deep Dive: Why setApprovalForAll Is the Single Most Dangerous Pattern
Most token approvals are scoped. A standard ERC-20 approve call names an amount, and even a large or unlimited amount is still bounded to a single token contract — an unlimited USDC approval can never touch your ETH, your NFTs, or any other asset, because the permission lives entirely inside the USDC contract's own bookkeeping. setApprovalForAll, defined as part of the ERC-721 and ERC-1155 NFT standards, works differently in a way that changes the entire risk calculation.
Calling setApprovalForAll on an NFT collection's contract and setting it to true grants the named operator address the right to transfer any and every token you currently hold, or will ever hold, from that specific collection, on your behalf, with no per-token confirmation required and no built-in expiration. It is not scoped to a single token ID, and it is not scoped to a dollar amount, because NFTs don't have a fungible amount to scope against in the first place — the permission is binary and collection-wide by design. If you own one token from that collection, the operator can move that one token. If you own fifty, the operator can move all fifty, in a single transaction, whenever they choose to call it.
This is precisely why setApprovalForAll shows up disproportionately often in the largest, most damaging NFT-holder drains. A blind-signing victim who approves a single scoped token approval for the wrong spender loses, at most, whatever amount that approval covers within one token contract. A blind-signing victim who approves setApprovalForAll for the wrong spender on a collection they hold multiple valuable pieces from can lose the entire collection in one drain transaction, executed at a time of the attacker's choosing, potentially days or weeks after the original signature, once enough approvals have accumulated to make draining them worthwhile in a single batch.
There is a legitimate reason this function exists and gets used constantly by real marketplaces: without it, a seller would need to submit a brand-new, separate approval transaction — and pay gas for it — every single time they wanted to list a different NFT from the same collection for sale. setApprovalForAll lets a marketplace's contract handle transfers for the entire collection once, so a seller can list, delist, and relist any token from that collection afterward without repeating the approval step. That legitimate convenience is exactly what a malicious version of the same request borrows: the framing "approve this once and you won't have to sign anything again" sounds like an efficiency feature in both cases, and the wallet prompt behind it can look nearly identical whether the spender is a real marketplace or an attacker's contract.
The practical implication is that setApprovalForAll should never be evaluated on the strength of its framing alone. The two questions that actually matter are: is the spender address genuinely the collection's documented, real marketplace or protocol contract, and do you actually need standing, indefinite access granted rather than a one-time, scoped alternative. If either answer is uncertain, that uncertainty is reason enough to stop before signing.
Worked Example: The Cloned Marketplace "Enable Trading" Flow
Hypothetical example — for education only.
Assume a reader owns several NFTs from a mid-cap collection and wants to list one for sale. A search engine ad, or a link shared in a group chat, points to what looks like the collection's usual marketplace — same layout, same collection banner image, same green "Verified Collection" badge, loading instantly and looking exactly like the real site the reader has used before. In reality, it's a cloned site on a domain that differs from the real marketplace by a single character, built specifically to intercept listing flows like this one.
The reader connects their wallet — a read-only step, as covered in the connections guide, that reveals nothing dangerous on its own — and picks the NFT they want to sell, entering a price. Instead of proceeding directly to a signed listing order, the site shows an intermediate screen: "Enable Trading for [Collection Name]," described as a "one-time setup step required before your first listing on this marketplace," with a single "Enable" button. This framing is deliberately chosen to sound like standard onboarding friction — the kind of setup step real marketplaces genuinely do use — rather than anything unusual.
The reader clicks Enable. The wallet prompt that follows is a call to the NFT collection's setApprovalForAll function, naming an attacker-controlled address as the operator and setting the approval to true. Nothing in the button's label mentioned setApprovalForAll, an entire collection, or unlimited scope — it said "enable trading," which sounds like exactly the kind of account-configuration step a real marketplace legitimately does require before a first listing. Depending on the wallet's confirmation screen, the underlying request may show only the contract address and the raw function call, without translating it into the consequence: every NFT the reader owns from that collection can now be moved by the attacker's address, at any time, without any further confirmation.
The reader signs, expecting a routine setup step consistent with the site's own description. The intended listing may or may not actually appear afterward — some versions of this scheme complete a convincing-looking fake listing to avoid raising suspicion immediately, while others simply show an error and quietly do nothing further in that session. Either way, the actual damage was already done at the signature step: the attacker now holds a standing, collection-wide transfer permission and can drain every token the reader owns from that collection in a single transaction whenever they choose, independent of whatever the site displays afterward.
The failure point mirrors the general pattern this whole guide is built around: the reader's mistake wasn't carelessness about connecting, and it wasn't failing to notice an obviously broken or unprofessional site — the clone was convincing precisely because it wasn't obviously broken. The mistake was trusting the button's framing ("enable trading," a plausible one-time setup step) instead of checking two verifiable facts that would have caught it: whether the spender address matched the real marketplace's actual documented contract, and whether the wallet's own simulation or raw request data showed a collection-wide setApprovalForAll rather than a scoped, single-listing approval.
How Wallet Simulation Helps — and Where It Falls Short
The core problem this entire category of attack exploits is a translation gap: a wallet's raw confirmation prompt has historically shown technical data — a contract address, a function name, a hex-encoded parameter — rather than a plain description of the real-world consequence. Reading raw calldata well enough to recognize setApprovalForAll and reason through its implications is a skill most wallet holders, understandably, never develop and shouldn't need to in order to use crypto safely.
Transaction simulation closes most of that gap. Rather than just displaying the request, a simulating wallet or browser extension actually runs the pending transaction against a copy of current blockchain state before asking for a signature, then reports back what would happen in plain language: "this will grant [operator address] unlimited transfer rights over your entire [Collection Name] holdings" instead of a bare function name and a boolean flag. That single sentence is the difference between a blind-signing decision and an informed one — it directly answers the exact question the red-flag checklist above is built around, without requiring the signer to know what setApprovalForAll even is.
Applied to the cloned-marketplace example above, a simulating wallet confronted with the "Enable Trading" button's underlying request would ideally surface something close to: "This transaction grants 0xABC... permission to transfer every NFT you own from [Collection Name], with no expiration, and does not list any specific item for sale." Set next to a button that said "Enable Trading," that mismatch between framing and actual effect is exactly the kind of discrepancy simulation exists to catch, and it gives a reader concrete grounds to stop and investigate the spender address before signing, rather than a vague unease they might talk themselves out of.
Simulation is not infallible, though, and treating it as a guarantee is its own mistake. A simulator can only report on the state it can observe and the logic it can execute at the moment of simulation; a contract designed to behave differently when actually called later, or one using techniques specifically built to evade automated analysis, can still slip past a simulation that reports nothing unusual. Simulation dramatically improves the odds of catching a disguised request, and using a wallet or extension that offers it is a genuinely high-value habit — but it belongs alongside the manual checklist above, as a strong second layer, not a replacement for actually reading what a request names as its spender and its scope.
Misconceptions Versus Reality
| Misconception | Reality |
|---|---|
| If a site looks professional and well-designed, the approval requests it makes are safe | Visual polish has no bearing on the smart contract logic behind an approval request; a cloned site can copy real branding pixel-for-pixel while pointing every approval at a completely different, attacker-controlled address |
| An unlimited approval amount always means the request is malicious | Some legitimate protocols request unlimited amounts purely to save on repeated gas costs; the red flag is an unlimited amount combined with an unfamiliar spender or an action that plainly doesn't need repeated access, not the number alone |
| setApprovalForAll is just a bigger version of a normal token approval | It's categorically different — it grants rights over an entire NFT collection rather than a bounded amount of one token, with no built-in scope limit, which is why it's disproportionately behind the largest NFT-holder drains |
| My wallet would warn me clearly if a request were dangerous | Warning quality varies significantly across wallets, browsers, and versions; some show only raw technical data with no plain-language translation of the actual consequence |
| If a transaction simulator shows no warning, the request must be safe | Simulation meaningfully reduces risk but isn't infallible; it reports what it can observe and execute at that moment, and can be evaded by contracts designed to behave differently later or built to resist automated analysis |
| Approving setApprovalForAll once on a marketplace I already trust is a permanent non-issue | The approval itself doesn't expire and doesn't distinguish between the marketplace acting normally and its contract being exploited or maliciously upgraded later, so it's worth revoking once you're done actively trading rather than leaving it open indefinitely |
Common Mistakes
Two specific habits account for a large share of losses tied to malicious approval transactions, and both are worth naming precisely because each is easy to fall into even when someone generally knows better in the abstract.
The first is approving setApprovalForAll on marketplaces "for convenience" without actually understanding what scope is being granted. Many active NFT traders click through this exact prompt regularly on marketplaces they've used for months, because it genuinely does remove repeated approval friction for legitimate listing activity, and because the prompt itself becomes familiar enough to stop registering as something worth reading closely. That familiarity is precisely what a cloned site's identical-looking "enable trading" prompt exploits — the muscle memory built from approving the real version many times makes approving a fake version feel like nothing unusual at all.
The second is not checking the requested spender address against the marketplace's actual, documented contract address. Most people never look this up in the first place, and even fewer check it again on a marketplace they believe they already recognize, because checking a spender address against an official source feels like an extra step reserved for obviously unfamiliar sites rather than one to apply consistently. But a cloned site's entire function is to look exactly as familiar as the real one; the spender address is very often the one piece of the interaction a clone cannot fake convincingly, because it points to a contract the attacker actually controls, and it's the one detail a reader can verify independently of how the surrounding page looks or behaves.
Risks, Limitations, and Exceptions
- Legitimate marketplaces and protocols do request setApprovalForAll and unlimited amounts for genuine efficiency reasons; neither pattern is inherently malicious on its own, only worth verifying against the specific spender and action involved.
- Wallet confirmation screens and the plain-language quality of what they show vary significantly across wallets, browsers, extension versions, and mobile versus desktop, so the amount of built-in protection a reader gets by default is not consistent or guaranteed.
- Transaction simulation tools reduce but do not eliminate risk, and can be defeated by contracts specifically designed to behave differently at execution time or to evade automated pre-signature analysis.
- Verifying a spender address against an "official" source is only as reliable as that source; always cross-check against a project's own documentation or a well-established block explorer rather than a single unverified link.
- Even a scoped, non-unlimited approval to a malicious spender still carries risk up to whatever amount was granted; the checklist in this guide reduces risk across all approval types, not just the unlimited or collection-wide ones.
- Revoking a standing approval requires a separate on-chain transaction and gas fee, and does nothing to recover assets already transferred before the revocation happens.
Practical Implementation Checklist
- Before signing any approval or permit request, read the spender address and confirm it matches the specific action you're trying to take.
- Cross-check an unfamiliar spender address against the site's own documentation or a reputable block explorer rather than trusting it because the request appeared on a familiar-looking page.
- Treat an unlimited approval amount as worth a second look whenever the action you're taking is plainly a one-time event, not standing, repeated access.
- Treat any request involving setApprovalForAll as categorically higher-risk, and verify the operator address against the collection's real, documented marketplace contract before approving.
- Weigh how you arrived at the site — deliberate navigation versus an unsolicited link or ad — as part of how much scrutiny the request deserves.
- Use a wallet or browser extension that simulates pending transactions and read what it reports before confirming, rather than skipping past it.
- If a simulation shows an outcome that doesn't match what you expected the action to do, stop and do not sign, regardless of how legitimate the rest of the site appears.
- Periodically review standing approvals, including any setApprovalForAll grants, through a reputable on-chain allowance-checking tool and revoke ones you no longer actively need.
- If you ever discover an approval you don't recognize or can't account for, revoke it immediately and check your recent transaction history and balances for signs it was already used.
Tool Opportunity
A dedicated Swoopr tool should help readers evaluate a pending approval or permit request against this checklist in plain language before they sign.
Recommended inputs: the requesting site's domain, and — entered manually by the user, never auto-collected — the spender address, requested amount, and function name shown in the wallet's confirmation screen.
Expected outputs: a plain-language flag for each checklist item (spender familiarity, unlimited amount, setApprovalForAll usage, site-navigation context) and a summary explaining what the request would actually grant if approved.
Validation requirements: never request wallet connection, a seed phrase, or a private key as part of using the tool itself, clearly label all output as educational guidance rather than a guarantee that any specific request is safe, and direct genuinely uncertain cases toward independently verifying the spender address and using a dedicated transaction-simulation tool before signing.
Sources
- EIP-721: Non-Fungible Token Standard — the Ethereum standard that defines setApprovalForAll and the collection-wide transfer permission it grants, referenced throughout this guide.
- EIP-20: Token Standard — the standard defining the approve function and scoped spending allowances that ordinary ERC-20 token approvals rely on.
- Federal Trade Commission, "What To Know About Cryptocurrency Scams" — consumer guidance on recognizing crypto-targeted fraud, including deceptive approval and permission requests.
Conclusion
An approval prompt is not a formality to click through on the way to what you actually meant to do — it is the decision itself. The spender address, the requested amount, and the specific function being called are all verifiable details sitting right in front of you, and checking them against what the action you're taking actually requires catches the overwhelming majority of malicious approval attempts before they succeed. setApprovalForAll deserves the most caution of all, precisely because its blast radius is an entire collection rather than a single item, and because its legitimate convenience framing is exactly what a malicious version borrows. Combine the manual checklist in this guide with a wallet that simulates and plainly explains what you're about to sign, and blind signing stops being blind.
Related Reading
- Token Approvals & Blind Signing — the parent hub covering the broader family of approval and permit risks beyond the specific red flags covered here.
- NFT approval risks — a closer look at how NFT-specific approvals like setApprovalForAll differ from ordinary token approvals and what makes NFT collections a common drain target.
- Blind signing explained — why raw transaction data is hard to read at the wallet-prompt level and how that gap gets exploited.
- Token allowance checker tools — how to review and revoke standing approvals across your wallet using a reputable on-chain allowance checker.
Frequently Asked Questions
What is the single most important thing to check before approving a transaction?
Whether the spender address requesting the approval is one you actually recognize and expect for the specific action you're trying to take. A legitimate marketplace listing, a DEX swap, and a staking deposit each have a known, verifiable contract address; if the requested spender doesn't match what the site's own documentation or a block explorer shows for that action, treat it as a red flag regardless of how the request is worded.
Is it always dangerous if a wallet asks for an unlimited approval amount?
Not always, but it's a signal that deserves scrutiny. Some legitimate protocols default to an unlimited allowance purely for gas-fee convenience, so you don't have to pay for a new approval on every future transaction. The danger isn't the number itself, it's an unlimited amount requested for an action that plainly doesn't need repeated access, such as a one-time NFT sale or a single token transfer, since a malicious contract benefits from unlimited access exactly the same way a convenience-minded legitimate one does.
Why is setApprovalForAll more dangerous than a normal token approval?
A standard ERC-20 approval grants a spender rights over a specific amount of a specific token. setApprovalForAll, used by NFT collections, grants an operator address transfer rights over every token you hold in that entire collection, not one token ID, with no dollar or quantity limit built into the permission itself. A single malicious setApprovalForAll signature can therefore empty an entire valuable NFT collection in one transaction, which is disproportionately how major NFT-holder drains have actually happened.
Does a professional-looking website mean its approval requests are safe?
No. Visual design has no bearing on the smart contract logic behind an approval request. A cloned or fraudulent site can copy a real marketplace's layout, branding, and even its exact wording pixel-for-pixel while pointing every approval at a completely different, attacker-controlled spender address. Judge an approval by what it technically authorizes and by independently verifying the spender address, never by how polished the surrounding page looks.
How does wallet simulation help catch a malicious approval?
Wallet simulation tools execute the pending transaction against a copy of current blockchain state before you sign, then translate the technical result into a plain-language outcome, such as showing that a request will grant an unfamiliar address unlimited transfer rights over an entire NFT collection. This turns a raw, hard-to-read technical payload into a decision a non-technical user can actually evaluate, catching a mismatch between how a request is framed and what it actually does.
Is it safe to approve setApprovalForAll on a marketplace I use regularly?
It carries real, ongoing risk even on a marketplace you trust and use regularly, because the approval itself doesn't expire and doesn't distinguish between the marketplace acting on your behalf and the marketplace's contract being exploited or upgraded maliciously later. If you approve it, confirm the spender is the marketplace's actual documented contract address, understand you're granting standing access to the entire collection rather than a single listing, and revoke it once you're done actively trading if you don't need it left open.
What should I do if I already approved something that looks suspicious?
Revoke the approval immediately using a reputable on-chain allowance-checking tool, which submits a new transaction setting the spender's permission back to zero. Revoking stops any future use of that permission but cannot recover assets already moved before the revocation, so check your wallet's transaction history and token or NFT balances for signs a transfer already happened, and move remaining assets to a new wallet if you have any doubt about further exposure.