EVM Wallet Approval & Permit2 Risk Auditor — Find the unlimited approvals that can still pull your tokens.
Audit any Ethereum, Base, or Arbitrum wallet you own: read the live ERC-20 allowance() and Permit2 sub-allowance for every curated and discovered token/spender pair, see the balance actually at risk behind each one, classify the spender (EOA, unverified contract, unlabeled contract, or curated protocol), and get exact approve(spender, 0) revoke and Permit2 lockdown call-data to sign in your own wallet.
SKU: evm-approval-auditor · Skills: evm-approval-auditor-setup + evm-approval-auditor · Tested: 1,181 lines stdlib Python, 87 unit tests
What It Does
- Live allowance reads across Ethereum (
eth, 1), Base (base, 8453), and Arbitrum One (arb, 42161): ERC-20allowance(owner, spender)plus Permit2allowance(owner, token, spender)(amount, expiration, nonce) over curated stablecoins, WETH, WBTC and LSTs, Blockscout-discovered holdings, and boundedeth_getLogsApproval-event discovery (--lookback-blocks, default 20000). - Spender classification with balance-at-risk per pair:
EOA_SPENDERand unverified unlabeled contracts (UNVERIFIED_SPENDER) are CRITICAL, unlimited allowances to unlabeled verified contracts (UNKNOWN_VERIFIED_SPENDER) are HIGH, unlimited allowances to curated spenders (Uniswap Permit2 & routers, 1inch, CoW Protocol, 0x, ParaSwap, Morpho Blue, Aave V3) are MEDIUM, plusPERMIT2_ACTIVE_SUBALLOWANCE/PERMIT2_EXPIRED_SUBALLOWANCE. - Non-custodial remediation call-data: exact
to+dataforapprove(spender, 0)on each flagged token and a single batched Permit2lockdown((token, spender)[])transaction, displayed for you to submit from your own wallet (Rabby, MetaMask, Safe, or hardware signer). - Stateful delta monitor (
--state PATH --delta): emitsNEW_APPROVAL,ALLOWANCE_INCREASED, andAPPROVAL_REVOKEDevents between runs, with--jsonoutput and exit codes 0 clean / 1 MEDIUM / 2 HIGH / 3 CRITICAL / 10 bad input / 11 degraded sources. 1,181 lines stdlib Python, 87 passing unit tests.
Live output (Ethereum Mainnet: two public wallets, ERC-20 + Permit2 allowances)
Sample disclosure: this is a representative sample, not a customer report. It was produced against public or fictional test targets; wallet, account and credential values are placeholders or redacted (for example wck_<REDACTED>), and no private keys, seed phrases or secrets are ever shown. Your own report will differ in content and length.
snapshot 2026-10-27 08:34:01 UTC | tool=evm-approval-auditor
endpoints https://ethereum-rpc.publicnode.com
owner eth:0x88298912d3281d57ca6b3a685ee0243776f3444b
coverage tokens=7 (blockscout 1, curated 6) spenders=12 (curated 11, user 1) erc20_pairs=84 permit2_pairs=7
logs full [26277876..26282875] 5000 block(s), 1 chunk(s)
holdings blockscout ok (1 token(s))
approval USDC -> 0xb300000b72deaeb607a12d5f54773d1c19c7028d [unlabeled] allowance=UNLIMITED balance=0 at_risk=0 HIGH/REVOKE
spender 0xb300000b72deaeb607a12d5f54773d1c19c7028d [unlabeled] contract 180B verified=yes
owner eth:0xd8da6bf26964af9d7eed9e03e53415d37aa96045
coverage tokens=6 (curated 6) spenders=12 (curated 11, user 1) erc20_pairs=72 permit2_pairs=16
logs full [26277876..26282875] 5000 block(s), 1 chunk(s)
holdings blockscout unavailable (The read operation timed out)
approval DAI -> 0x000000000022d473030f116ddee9f6b43ac78ba3 [Uniswap Permit2 (canonical)] allowance=UNLIMITED balance=14.372082162212001768 at_risk=14.372082162212001768 MEDIUM/REDUCE
approval DAI -> 0x68b3465833fb72a70ecdf485e0e4c7bd8665fc45 [Uniswap SwapRouter02] allowance=UNLIMITED balance=14.372082162212001768 at_risk=14.372082162212001768 MEDIUM/REDUCE
approval DAI -> 0xc92e8bdf79f0507f65a392b0ab4667716bfe0110 [CoW Protocol GPv2VaultRelayer] allowance=UNLIMITED balance=14.372082162212001768 at_risk=14.372082162212001768 MEDIUM/REDUCE
approval WETH -> 0xc92e8bdf79f0507f65a392b0ab4667716bfe0110 [CoW Protocol GPv2VaultRelayer] allowance=UNLIMITED balance=1.46652803708515807 at_risk=1.46652803708515807 MEDIUM/REDUCE
approval USDT -> 0xc92e8bdf79f0507f65a392b0ab4667716bfe0110 [CoW Protocol GPv2VaultRelayer] allowance=UNLIMITED balance=291.368219 at_risk=291.368219 MEDIUM/REDUCE
spender 0x000000000022d473030f116ddee9f6b43ac78ba3 [Uniswap Permit2 (canonical)] contract 9152B verified=yes
spender 0x68b3465833fb72a70ecdf485e0e4c7bd8665fc45 [Uniswap SwapRouter02] contract 24497B verified=yes
spender 0xc92e8bdf79f0507f65a392b0ab4667716bfe0110 [CoW Protocol GPv2VaultRelayer] contract 4590B verified=yes
findings
[HIGH ] UNKNOWN_VERIFIED_SPENDER: USDC allowance UNLIMITED to 0xb300000b72deaeb607a12d5f54773d1c19c7028d [unlabeled]; balance 0, at risk 0 USDC; unlabeled contract (180 bytes), source-verified as Diamond
action=REVOKE to=0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 approve(0xb300000b72deaeb607a12d5f54773d1c19c7028d, 0)
data=0x095ea7b3000000000000000000000000b300000b72deaeb607a12d5f54773d1c19c7028d0000000000000000000000000000000000000000000000000000000000000000
[MEDIUM ] UNLIMITED_KNOWN_SPENDER: DAI allowance UNLIMITED to 0x000000000022d473030f116ddee9f6b43ac78ba3 [Uniswap Permit2 (canonical)]; balance 14.372082162212001768, at risk 14.372082162212001768 DAI; curated spender; consider an exact-amount approval instead of unlimited
action=REDUCE to=0x6b175474e89094c44da98b954eedeac495271d0f approve(0x000000000022d473030f116ddee9f6b43ac78ba3, 0)
data=0x095ea7b3000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba30000000000000000000000000000000000000000000000000000000000000000
[MEDIUM ] UNLIMITED_KNOWN_SPENDER: DAI allowance UNLIMITED to 0x68b3465833fb72a70ecdf485e0e4c7bd8665fc45 [Uniswap SwapRouter02]; balance 14.372082162212001768, at risk 14.372082162212001768 DAI; curated spender; consider an exact-amount approval instead of unlimited
action=REDUCE to=0x6b175474e89094c44da98b954eedeac495271d0f approve(0x68b3465833fb72a70ecdf485e0e4c7bd8665fc45, 0)
data=0x095ea7b300000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc450000000000000000000000000000000000000000000000000000000000000000
[MEDIUM ] UNLIMITED_KNOWN_SPENDER: DAI allowance UNLIMITED to 0xc92e8bdf79f0507f65a392b0ab4667716bfe0110 [CoW Protocol GPv2VaultRelayer]; balance 14.372082162212001768, at risk 14.372082162212001768 DAI; curated spender; consider an exact-amount approval instead of unlimited
action=REDUCE to=0x6b175474e89094c44da98b954eedeac495271d0f approve(0xc92e8bdf79f0507f65a392b0ab4667716bfe0110, 0)
data=0x095ea7b3000000000000000000000000c92e8bdf79f0507f65a392b0ab4667716bfe01100000000000000000000000000000000000000000000000000000000000000000
[MEDIUM ] UNLIMITED_KNOWN_SPENDER: WETH allowance UNLIMITED to 0xc92e8bdf79f0507f65a392b0ab4667716bfe0110 [CoW Protocol GPv2VaultRelayer]; balance 1.46652803708515807, at risk 1.46652803708515807 WETH; curated spender; consider an exact-amount approval instead of unlimited
action=REDUCE to=0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 approve(0xc92e8bdf79f0507f65a392b0ab4667716bfe0110, 0)
data=0x095ea7b3000000000000000000000000c92e8bdf79f0507f65a392b0ab4667716bfe01100000000000000000000000000000000000000000000000000000000000000000
[MEDIUM ] UNLIMITED_KNOWN_SPENDER: USDT allowance UNLIMITED to 0xc92e8bdf79f0507f65a392b0ab4667716bfe0110 [CoW Protocol GPv2VaultRelayer]; balance 291.368219, at risk 291.368219 USDT; curated spender; consider an exact-amount approval instead of unlimited
action=REDUCE to=0xdac17f958d2ee523a2206206994597c13d831ec7 approve(0xc92e8bdf79f0507f65a392b0ab4667716bfe0110, 0)
data=0x095ea7b3000000000000000000000000c92e8bdf79f0507f65a392b0ab4667716bfe01100000000000000000000000000000000000000000000000000000000000000000
exit_code 2
SCOPE_NOTE: Read-only: only eth_blockNumber, eth_call, eth_getCode, eth_getStorageAt and eth_getLogs, plus public Sourcify/Blockscout lookups. Never asks for private keys or seed phrases; no signing, no transaction is built for or broadcast by the tool; revoke (approve(spender, 0)) and Permit2 lockdown call-data is displayed for the owner to submit themselves. Reports current allowance state for the tokens and spenders it checked and states its coverage window; "no findings" never means "no approvals exist" (NFT setApprovalForAll and unlisted tokens/spenders are outside v1 unless supplied). Spender labels come from a curated list and Sourcify/Blockscout; an unlabeled spender is unknown, not malicious. No financial, legal or tax advice. Refuses: scanning to target third-party wallets for exploitation, ranking wallets by balance, or building phishing/drainer lists.
What It Does Not Do
- Strictly read-only (
eth_blockNumber,eth_call,eth_getCode,eth_getStorageAt,eth_getLogs): never asks for private keys or seed phrases, and never signs, builds for submission, or broadcasts a transaction. - “No findings” never means “no approvals exist”: coverage is the stated tokens, spenders, and log window. NFT
setApprovalForAlland unlisted tokens/spenders are outside v1 unless supplied with--tokens/--spenders. - An unlabeled spender is unknown, not malicious; refuses to scan third-party wallets for exploitation, rank wallets by balance, or build phishing/drainer lists. Not financial, legal, or tax advice.
Pinned Runtime (SHA-256)
/runtime/evm_approval_auditor.py— SHA-256eab5dc79cb998a2ac39093748e6aba186f88a23e28f1155f807ade3a02eaa518/runtime/bot_common.py— SHA-256d1941b61b95ca664e4c1286c3bf1918c00e976c2c1601199b19200257650e526
The setup skill refuses to install either file if its SHA-256 does not match the pinned value above. Runtime URLs are license-gated: send X-License-Key: wcl_... or X-Agent-Key: wck_... (unauthenticated requests get 401). The served file carries a per-license watermark block (5 lines), so compare the X-Canonical-SHA256 response header (or the SHA-256 after stripping the block) against the pin. The recommended path is the setup skill installer.
Licensing & Setup
One-time license, up to 3 workspace-reset rebinds. On Turn 1 the evm-approval-auditor-setup skill verifies your agent key, binds your wcl_... code through the read-only license helper, and installs the SHA-256-pinned bot_common.py and evm_approval_auditor.py runtime. The license code is never printed in chat.
One wcl_... key, two runtimes. Your license key works inside Grok Bot and from any local terminal or IDE agent (Cursor, Claude Code, Windsurf, CI/CD) via the standalone single-file Python 3 CLI (/runtime/evm_approval_auditor.py) — Python 3.10+ standard library only, zero pip install dependencies, with --json / --markdown output.