Skip to main content

🔍 ERC20 Checker

Scan ERC20 approvals · Assess risk · Build revoke transactions

Zero dependencies · Pure Python · Multi-chain

PyPI License: MIT Tests


⚡ Quick Start

pip install erc20-checker

# Scan all approvals
erc20-check scan ethereum 0xYourWalletAddress

# Check a specific allowance
erc20-check allowance ethereum 0xYourWallet 0xUSDC 0xSpender

# Build revoke transactions for high-risk approvals
erc20-check revoke ethereum 0xYourWalletAddress

Python API

from erc20_checker.scanner import scan_approvals
from erc20_checker.risk import risk_report, summary

# Scan all approvals for a wallet on Ethereum
result = scan_approvals("ethereum", "0xYourWalletAddress")

# Add risk assessment
report = risk_report(result["approvals"])
print(summary(report))
# {'total': 3, 'highRisk': 1, 'mediumRisk': 0, 'lowRisk': 2}

That's it. Three lines of code to audit every ERC20 approval on your wallet.

🛡️ Risk Levels

Level Criteria Meaning
🔴 HIGH Unlimited approval (≥ 2¹²⁸) Spender can drain all your tokens. Revoke immediately.
🟡 MEDIUM Unknown spender contract Spender is not a recognized protocol. Exercise caution.
🟢 LOW Finite approval, known spender Normal DeFi interaction. Low risk.

📦 Install

pip install erc20-checker

Or from source:

git clone https://github.com/counterfactual5/erc20-checker.git
cd erc20-checker
pip install -e .

🔧 Usage

Scan All Approvals

from erc20_checker.scanner import scan_approvals

result = scan_approvals(
    chain="base",
    wallet="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    start_block=0,
    max_logs=5000,
)

for approval in result["approvals"]:
    print(f"{approval['tokenSymbol']}: {approval['humanAllowance']} → {approval['spender']}")

Check Single Allowance

from erc20_checker.allowance import query_allowance

result = query_allowance(
    chain="ethereum",
    wallet="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    token="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",  # USDC
    spender="0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",  # Uniswap Router
)
print(result["humanAllowance"])  # e.g. "115792089237316195423570985008687907853269984665640564039457584007913129639935"

Risk Assessment

from erc20_checker.risk import risk_report, summary

report = risk_report(result["approvals"])
for entry in report:
    print(f"{entry['tokenSymbol']}: {entry['riskLabel']} (infinite: {entry['isInfinite']})")

# Aggregate
print(summary(report))

Build Revoke Transactions

from erc20_checker.revoke import build_revoke_tx, build_revoke_batch

# Single revoke
tx = build_revoke_tx(
    token_address="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    spender="0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",
)
# tx = {"to": "0xa0b8...", "data": "0x095ea7b3...00000000", "value": "0"}

# Batch revoke for all high-risk approvals
high_risk = [e for e in report if e["riskLevel"] == 3]
batch = build_revoke_batch(high_risk)

📋 Example Output

{
  "chain": {"key": "ethereum", "chainId": 1},
  "wallet": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
  "approvalCount": 3,
  "approvals": [
    {
      "tokenAddress": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
      "tokenSymbol": "USDC",
      "spender": "0x68b3465833fb72a70ecdf485e0e4c7bd8665fc45",
      "rawAllowance": "115792089237316195423570985008687907853269984665640564039457584007913129639935",
      "humanAllowance": "115792089237316195423570985008687907853269984665640564039457584007913129639935",
      "decimals": 6,
      "lastApprovalBlock": 19283000,
      "riskLevel": 3,
      "riskLabel": "🔴 HIGH",
      "isInfinite": true
    }
  ]
}

🔗 Supported Chains

Chain Chain ID Etherscan
Ethereum 1 etherscan.io
Base 8453 basescan.org
Arbitrum 42161 arbiscan.io
Optimism 10 optimistic.etherscan.io
Polygon 137 polygonscan.com

📊 Comparison

Feature erc20-checker revoke.cash Manual (Etherscan)
Programmatic API ✅ ❌ (web only) ❌
Multi-chain ✅ 5 chains ✅ Per-chain manual
Risk scoring ✅ Built-in ⚠️ Basic ❌
Batch revoke data ✅ ✅ ❌
Zero dependencies ✅ N/A N/A
Self-hosted / offline ✅ ❌ ❌

⚙️ Configuration

Set environment variables:

# Required for scanning (Etherscan API)
export ETHERSCAN_API_KEY="your-api-key"

# RPC URL (auto-detected by chain name)
export ETHEREUM_RPC_URL="https://eth.llamarpc.com"
export BASE_RPC_URL="https://mainnet.base.org"
export ARBITRUM_RPC_URL="https://arb1.arbitrum.io/rpc"
# ... or use a generic fallback
export RPC_URL="https://eth.llamarpc.com"

⚠️ Security

  • Read-only: This library only reads on-chain data and builds unsigned transaction payloads. It never signs or broadcasts transactions.
  • No private keys: No wallet private keys or seed phrases are ever needed.
  • No external dependencies: Only Python standard library — minimal attack surface.
  • Verify before revoking: Always verify the to address and data in the revoke transaction before signing. The calldata should be approve(spender, 0).

🛠️ Development

git clone https://github.com/counterfactual5/erc20-checker.git
cd erc20-checker

# Install with dev deps
uv pip install -e ".[dev]"

# Run tests
uv run pytest tests/ -v

🗺️ Roadmap

  • Risk scoring (infinite + unknown spender detection)
  • Revoke transaction builder
  • Multi-chain support (5 chains via Etherscan v2)
  • CLI tool (erc20-check command)
  • Interactive HTML dashboard
  • Multi-wallet batch scanning
  • Gas estimation for revoke transactions
  • Discord / Telegram bot integration

📄 License

MIT © 2026 counterfactual5

Metadata

Release files for erc20-checker 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for erc20-checker 0.1.0
File Interpreter ABI Platform
erc20_checker-0.1.0-py3-none-any.whl Python 3 none any Details

Release files / erc20_checker-0.1.0-py3-none-any.whl

Download URL erc20_checker-0.1.0-py3-none-any.whl
Size 18.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4c346c33285089bfc899fdfb81a94de17d8038f7c60a56249165413120345c92
BLAKE2b-256 checksum
How to use checksums
6d2467caf576264108a5dccbf0d739af4d302193ba9bb76bce08c34b5046da11
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Release history Release notifications | RSS feed

This release

0.1.0 This release

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page