The contract is live. It holds real value. Right now, if someone started draining it, the first you'd hear about it would be a Discord message from a user, or a tweet from a wallet-tracking bot, or your treasury balance looking wrong on a Tuesday morning. You would not hear about it from your own systems. That gap — between the exploit and your awareness of it — is where protocols die.
A normal web app gives you time. A bad deploy degrades gracefully, error rates climb, you roll back, users grumble. On-chain there is no rollback and there is no grace. An attacker who finds a drain executes it in one transaction or a tight loop of them, and by the time you've noticed, the funds are bridged to three chains and through a mixer. The window between "something is wrong" and "the money is gone" is measured in blocks, not hours.
So the question is not whether you monitor. It's whether your monitoring runs at the speed of the chain.
Why your existing observability stack doesn't cover this
You probably have Datadog or Grafana watching your backend. CPU, memory, request latency, error rates. None of it sees on-chain. Your contract emitting a Transfer event for half the treasury is invisible to an APM tool that only knows about your API servers. The blockchain is a separate system with its own state, and your application metrics tell you nothing about it.
Worse, the interesting events often happen with zero involvement from your infrastructure. An attacker doesn't call your API. They call your contract directly, from their own tooling, against an RPC node you don't operate. Your servers stay quiet and green while the contract bleeds. Monitoring that depends on traffic hitting your backend is structurally blind to the most important class of incident.
On-chain monitoring is a distinct discipline. It watches contract state and the event log, not your servers.
Event monitoring: the contract's own audit trail
Every meaningful state change in a well-built contract emits an event. That's not just for indexers — it's your alerting substrate. You ingest the event log for your contracts and you alert on the ones that matter.
event Withdraw(address indexed user, uint256 amount);
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
event Paused(address account);
event Upgraded(address indexed implementation);
The four above are not equal. A Withdraw is routine. A RoleGranted, Paused, or Upgraded is, in most protocols, a once-a-quarter event — and if it fires when no human on your team initiated it, you have an active incident. The discipline is to classify every event your contracts emit into routine, notable, and never-without-a-human, then wire alerts to the last two categories with escalation that wakes someone up.
The implementation is a worker subscribing to logs filtered by your contract addresses and topic hashes. You decode against the ABI, match against your classification, and route. The trap teams fall into is alerting on volume rather than meaning — a thousand Transfer events an hour is noise; one Upgraded event you didn't schedule is the whole game.
Anomaly detection on the things that move
Static thresholds are a start and not enough. "Alert if a single withdrawal exceeds 10% of TVL" catches the smash-and-grab. It misses the patient attacker who drains 2% per block across forty blocks, each transaction individually unremarkable.
So you watch rates of change, not just magnitudes. Outflow velocity over a rolling window. The number of distinct addresses interacting in a block versus the baseline. The ratio of a function's call count this hour against its trailing seven-day average. A contract that normally sees forty redeem calls a day suddenly seeing four hundred in ten minutes is the signal, even if no single call trips a threshold.
The hard part is the baseline. You cannot define "abnormal" without knowing normal, and normal for a six-week-old protocol is a moving target. The honest approach is to start with conservative absolute thresholds at launch, accumulate two to four weeks of real behavior, then layer relative anomaly detection on top once you have a baseline worth comparing against. Anyone selling you statistical anomaly detection on day one is selling you false positives.
Admin-action alerts: trust but verify your own multisig
The highest-privilege operations in your system — upgrades, role grants, pause, parameter changes, treasury moves — should each fire an alert the moment they land on-chain, regardless of who initiated them. Especially when you initiated them.
This sounds redundant. You know you scheduled the upgrade. The point is the operations you did not schedule. If a signer's key is compromised and the attacker pushes a malicious upgrade through your timelock, the alert at submission time is your only chance to react during the timelock window before it executes. An admin-action alert turns your timelock from a passive delay into an active defense, because it gives a human the chance to see the queued action and trigger your emergency response while there's still time.
Wire every privileged function to an alert. Cross-reference against your own change calendar. Anything on-chain that isn't on the calendar is an incident until proven otherwise.
Balance watches: the ground truth
Events can lie by omission — a poorly written contract might move value without a clean event, or an attacker might find a path your event coverage didn't anticipate. So you also watch the thing that cannot lie: balances.
You poll the actual on-chain balances of every contract and treasury address that holds value, every block or every few blocks. You compute expected balance from the events you've processed. When measured and expected diverge beyond rounding, you alert hard. This is the backstop that catches what event monitoring misses, because it reconciles against chain state directly rather than trusting your model of it.
Balance watches also catch the boring failures: a fee that should have accrued and didn't, a bridge deposit that left one side and never arrived on the other, a reward pool draining faster than emissions math says it should. Money that moves when it shouldn't, and money that doesn't move when it should — both show up here.
The re-org caveat nobody mentions
Your monitoring reads recent blocks, and recent blocks can be reorganized. Alert on an unconfirmed transaction and you'll page your on-call for an event that gets orphaned a block later. The fix is confirmation depth: treat shallow events as provisional and only fire hard alerts after a chain-appropriate number of confirmations. On Polygon that's a handful of blocks for routine alerts; for the never-without-a-human category you want the alert fast and provisional, then confirmed. Calibrate the urgency to the depth, or you'll train your team to ignore the pager.
The tooling
You assemble this from parts rather than buying a box. A reliable event ingestion path — a private RPC node or a node provider with websocket subscriptions, because public endpoints throttle and drop logs exactly when network activity spikes, which is exactly when you need them. A decoder against your ABIs. A rules layer that classifies and thresholds. A routing layer into your existing paging — PagerDuty, Opsgenie, whatever already wakes your team — because the last thing you want is a separate on-call system for on-chain that nobody checks.
Off-the-shelf platforms like OpenZeppelin Defender Sentinels or Tenderly alerts cover the common cases and are a reasonable starting point. They handle event filtering and basic thresholds. What they don't do is encode your protocol's specific economic invariants — the relationships between balances and supply and emissions that only mean something in your system. Those you build. The right architecture is platform tools for the generic layer, custom watchers for the invariants that are unique to you.
On-call for on-chain
Detection without response is a louder way to lose money. The monitoring only matters if it connects to a human who can act and a contract that can be acted on.
That means a pause function or guardian role that can halt the contract fast, held by a key that's reachable in an emergency rather than locked in a four-of-seven multisig where two signers are asleep in another timezone. It means a runbook that says, per alert type, who decides, what they check, and what they do — written before the incident, not improvised during it. It means your on-call engineer can read the chain, knows what the alert means, and has practiced the pause on a fork. An emergency pause you've never executed is a theory, not a control.
What fixed looks like
Your treasury and contract balances reconcile against your event model every few blocks, and divergence pages someone. Every privileged on-chain action cross-checks against your change calendar automatically. Outflow velocity and call-rate anomalies alert against a real baseline, not a guess. Admin alerts fire at submission, inside the timelock window, while a human can still intervene. The alerts route into the same on-call rotation as the rest of your infrastructure, and the person who gets paged has run the pause drill on a fork and knows exactly what to do. You learn about incidents from your systems, in the first block — not from Twitter, an hour later, when the money is already gone.
This is for you if
You operate a contract on Polygon or another EVM chain that holds real value, and your current visibility into it is a block explorer you check when you remember to. Building production on-chain monitoring — event ingestion, anomaly detection against a real baseline, balance reconciliation, admin alerting, and the on-call integration to back it — is typically a $50k–$150k engagement depending on contract complexity and how much of your event architecture already exists. If your protocol secures real money, this is not optional infrastructure; it's the difference between a contained incident and a terminal one.
This is not for you if you're running a testnet experiment or a memecoin where there's nothing to monitor and nobody to page. Spend the money where there's value to protect.