On August 14, 2024, QuickNode released a comprehensive guide on building an ERC-20 token allowance checker using its Streams feature and PostgreSQL — a timely resource for anyone serious about DeFi security. Understanding and monitoring token allowances is one of the most critical skills for anyone interacting with decentralized finance protocols, yet many users — and even experienced developers — overlook the risks posed by excessive token approvals. This advanced tutorial walks through building a production-grade allowance monitoring system from scratch.
With Ethereum trading at approximately $2,662 and the DeFi ecosystem managing billions in total value locked, the security of ERC-20 token approvals directly affects every user who has ever interacted with a decentralized exchange, lending protocol, or yield farm. Every time you approve a smart contract to spend your tokens, you create a potential attack vector that persists until explicitly revoked.
The Objective
This tutorial aims to build a comprehensive ERC-20 token allowance checker that monitors all approval events across Ethereum smart contracts, stores them in a queryable database, and flags potentially dangerous approvals for review. The system uses QuickNode’s Streams feature for real-time blockchain data ingestion and PostgreSQL for persistent storage and analysis.
By the end of this walkthrough, you will understand how token allowances work at the contract level, how to capture approval events in real time, how to build a database schema optimized for allowance queries, and how to implement alerting logic that notifies you when risky approvals are detected. This is not a beginner tutorial — it assumes familiarity with Solidity, SQL, and blockchain data infrastructure.
Prerequisites
Before starting, ensure you have the following tools and accounts set up. You will need a QuickNode account with Streams enabled — the free tier provides sufficient throughput for monitoring a single chain. A PostgreSQL instance is required for data storage; version 14 or later is recommended for the JSONB and indexing optimizations used in the schema.
Working knowledge of the ERC-20 token standard is essential. Specifically, you should understand the approve() and allowance() functions, the Approval event signature, and the security implications of unlimited approvals (type(uint256).max). Familiarity with Ethers.js or Web3.js for reading contract state will be helpful for the verification components.
You will also need Node.js (v18 or later) for the data processing scripts, and a basic understanding of SQL for constructing queries against the allowance database. Docker is recommended for setting up the PostgreSQL instance quickly, though a managed database service like Supabase or Neon works equally well.
Step-by-Step Walkthrough
Step 1: Understanding the Approval Event. Every ERC-20 token emits an Approval event when a token holder grants spending permission. The event contains three parameters: the owner address, the spender address, and the approved amount. The standard event signature is Approval(address indexed owner, address indexed spender, uint256 value). Your allowance checker will monitor these events to build a complete picture of who can spend whose tokens.
Step 2: Configuring QuickNode Streams. Create a new Stream in your QuickNode dashboard targeting the Ethereum mainnet. Configure it to capture all Approval events by setting the filter to the event signature topic: 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. This keccak-256 hash uniquely identifies the ERC-20 Approval event across all tokens. Set the Stream to deliver data via webhook to your data processing endpoint.
Step 3: Database Schema Design. Create a PostgreSQL table optimized for allowance queries. The schema should include columns for the token contract address, owner address, spender address, approved amount, block number, transaction hash, and timestamp. Use composite indexes on (owner, token) and (spender, token) for efficient lookups. Store amounts as text to avoid JavaScript number precision issues with large uint256 values.
Step 4: Processing Stream Data. Build a Node.js webhook handler that receives Stream payloads, parses the event data, and upserts records into PostgreSQL. Handle the special case where an approval of zero represents a revocation — these should be tracked separately or marked accordingly. Implement idempotent processing using the transaction hash as a unique constraint to prevent duplicate entries.
Step 5: Building the Query Interface. Create SQL views and API endpoints for common queries: all allowances for a given address, all addresses that have approved a specific spender, allowances exceeding a threshold amount, and recent approvals within a time window. These queries power both the monitoring dashboard and the alerting system.
Step 6: Implementing Risk Scoring. Develop a risk scoring algorithm that flags potentially dangerous approvals. High-risk indicators include approvals to unknown or recently deployed contracts, approvals of unlimited amounts, approvals to contracts not verified on Etherscan, and multiple approvals to the same spender across different tokens. Cross-reference spender addresses against known exploit contract databases for additional context.
Troubleshooting
If your Stream is not capturing events, verify that the topic hash matches the Approval event signature exactly. Common mistakes include using the wrong event signature or applying case-sensitive filters. Ethereum addresses in events are returned in lowercase padded format — ensure your comparisons account for this.
Database performance issues typically stem from unoptimized queries on the large volume of approval events generated daily. If queries become slow, consider partitioning the table by block number ranges or implementing materialized views for frequently accessed aggregations. Index-only scans on the (owner, spender) composite index should handle most lookups efficiently.
Webhook reliability can be a concern during periods of high network activity. Implement a retry mechanism with exponential backoff for failed deliveries, and maintain a checkpoint system that tracks the last processed block number. If your webhook endpoint goes down, the checkpoint allows you to resume processing without data gaps.
Mastering the Skill
Once you have the basic allowance checker running, consider extending it with advanced features. Implement multi-chain support by adding Streams for additional EVM-compatible networks. Build a notification system that sends alerts via Telegram or Discord when high-risk approvals are detected. Create a public dashboard showing aggregated approval statistics for popular DeFi protocols.
For enterprise use, consider building a batch revocation tool that allows users to revoke multiple allowances in a single transaction, saving gas fees. Integrate with portfolio trackers to show allowance exposure alongside token holdings, giving users a complete picture of their DeFi risk profile.
The ability to monitor and audit token allowances is becoming increasingly valuable as the DeFi ecosystem grows more complex. Every new protocol, bridge, and yield optimizer introduces new approval requirements, and the cumulative attack surface grows with each interaction. Building your own monitoring tools gives you visibility and control that no third-party service can match.
Disclaimer: This article is for educational purposes only and does not constitute financial or security advice. Smart contract interactions carry inherent risks. Always audit code thoroughly and test on testnets before deploying to production environments.
building your own allowance checker instead of relying on revoke.cash is a power move. quickNode streams + postgres is a solid stack for it too
Every DeFi user should understand unlimited approvals. I audited my own wallets last month and found 47 active approvals I’d forgotten about.
47 is nothing. checked my main wallet once and had over 200. most from random airdrop claims i never even claimed
200 is wild. the scariest part is most of those are unlimited approvals to random contracts nobody has audited. one bug and its all gone
200 approvals is scary but most are to dead contracts with zero TVL now. the real risk is that one active contract that gets exploited
200 approvals and 190 are probably to dead contracts with zero TVL. but that one active contract with a vulnerability is all it takes
200 approvals and 190 are probably to dead contracts with zero TVL. but that one active contract with a vulnerability is all it takes
checked my wallet last month and found 3 unlimited approvals to contracts that were rug pulled in 2022. revoked everything immediately
unlimited approvals to rug pulled contracts is terrifying. those devs could wake up one day and drain every wallet that ever approved them
unlimited approvals to rug pulled contracts is terrifying. those devs could wake up one day and drain every wallet that ever approved them
47 is actually low for an active defi user. seen wallets with 300+ stale approvals to contracts that havent been updated in 2 years
building a custom checker with QuickNode streams is cool but revoke.cash exists for the 99% of users who wont go this far
building a custom checker with QuickNode streams is cool but revoke.cash exists for the 99% of users who wont go this far