Documentation
Contracts
SmartAlert watches a contract in three ways: by the events it emits, by the answers of its view functions and by the receipts of transactions sent to it. This page covers everything about the contract itself. Thresholds, the norm and the check on history are described in Rules.
On this page
| Feature | Plan |
|---|---|
| Ready rule sets by contract type | All plans |
| Uploading your own ABI | All plans |
| Contract state | Pro and above |
| Share of failed transactions | Business and above |
| Allowed senders | Business and above |
Ready rule sets by contract type
When you add a contract, SmartAlert reads its ABI and detects the type by its events. For each type found, a ready set of rules appears in "Suggestions". A contract can match several types: USDC, for example, is ERC-20, Pausable and a proxy. Then all matching sets are shown, and identical rules are not repeated. A contract without an ABI gets no sets.
| Type | Sign in the ABI | Rules |
|---|---|---|
| Safe (multisig) | AddedOwner, RemovedOwner, ChangedThreshold, ExecutionSuccess | Owners changed · Signature threshold changed · Transaction executed · Transaction failed · Module or guard enabled |
| ERC-20 (token) | Transfer(address,address,uint256), Approval | Tokens minted · Tokens burned · Transfer volume above normal · Transfers below normal · Large transfer |
| Ownable | OwnershipTransferred | Owner changed · Ownership transfer started |
| Pausable | Paused, Unpaused | Contract paused · Contract unpaused |
| AccessControl | RoleGranted, RoleRevoked | Role granted · Role revoked · Role admin changed |
| Proxy (ERC-1967) | Upgraded(address) | Contract upgraded · Proxy admin changed |
AddedOwner, RemovedOwner, ChangedThreshold, ExecutionSuccessTransfer(address,address,uint256), ApprovalOwnershipTransferredPaused, UnpausedRoleGranted, RoleRevokedUpgraded(address)A rule joins a set only if the event it needs is in the ABI. "Ownership transfer started", for example, is suggested only to a contract with OwnershipTransferStarted (Ownable2Step).
No rule turns on by itself. Tick the ones you need and press Accept: the rules are created in one step. Press Dismiss on one you do not need, and it is no longer suggested for this contract. An accepted rule is an ordinary rule: you can edit or delete it.
If the rules do not fit the plan limit, the whole set is still visible, and you can accept as many as the limit allows. Without a chosen channel the rules get the project's first channel. If there are no channels, the rule is created without one.
Uploading your own ABI
A verified contract gets its ABI automatically. For an unverified one, upload the ABI on the contract page. Without an ABI there are no events for rules and no functions for contract state.
What is accepted. A JSON ABI array or a Hardhat or Foundry build artifact: a file with the ABI in its abi field. Up to 1 MB, up to 2000 items in the ABI and at least one function.
How it is checked. SmartAlert reads the contract bytecode on the network and looks for every function of the ABI in it. If the contract is an ERC-1967 proxy, the implementation code is checked, not the proxy. If the contract already has events, the ABI must describe at least one of them: this catches an ABI from a different contract. If even one function is not found, the ABI is not saved, and the screen shows which functions are missing from the bytecode.
Who can upload. There is one ABI per contract, shared by all projects that watch it. While the contract has no ABI, any project with this contract can upload one (editor role and above). The first upload sets the ABI for everyone.
Replacing. Only the project that verified ownership of the contract can replace its ABI. The new ABI must contain every function and event that enabled rules of any project rely on. Otherwise the replacement fails and the previous ABI stays. Ownership cannot be verified for a contract without an owner() function: to replace its ABI, write to [email protected].
Contract state
A rule can watch the answer of a contract's view function instead of events: paused(), owner(), an oracle price latestAnswer(), totalSupply(), balanceOf(address). SmartAlert calls the function on a schedule and compares the answer with the condition.
Examples: "Contract paused" — paused() became true. "Owner changed" — owner() returned a different address.
Which functions fit. View and pure functions from the ABI with a single output: bool, address or a number (uint*, int*). Up to three arguments of types address, bool, uint*, int*, bytes32. Functions that return a string, bytes, an array or several values are listed but cannot be chosen.
Check the function. Before saving, press Check: SmartAlert calls the function on the network and shows the answer. If the contract has decimals(), the form offers to apply the decimals: a Chainlink feed price comes with 8 decimals. The check saves nothing. Up to 60 checks per hour per project.
Conditions.
| Function answer | Conditions |
|---|---|
bool, address | equals, not equals, changed |
| number | above, at least, below, at most, deviation from the norm |
bool, address"Changed" fires when the value changes. The notification shows what it was and what it became. The norm for numbers is the same as for events: the same hour over the past 7 days. Slow values such as totalSupply() barely move off the norm, a threshold suits them better.
How often we call. Once a minute, every 5 minutes, 15 minutes or an hour — by the most frequent rule on this function. A function without rules is not called. History starts with the first rule: past values are not read back, so the check on history is empty for a new function.
If the function reverts. A revert is not a value. The rule follows its "No data" policy, and "changed" compares with the value before the revert.
On the contract page. The "State" block shows the functions that have rules: the current value, when it changed and what it was before. Numbers get a chart, bool and address get a list of changes.
Notification.
- "paused() = true, was false"
- "owner() changed: 0x4a1d…e0c2 → 0x91c2…a7f0", both addresses link to the explorer
- "latestAnswer() 2,412.5 < 2,500"
Plus a link to the contract and the block the value was read at. In a webhook the function's answer comes in the alert.call field, see Webhook.
Limits. State rules count towards the common rule limit. Up to 20 different functions with arguments per contract in a project.
Plan. Pro and above. On Free the form is visible but locked. After a downgrade the rule keeps working; you can edit it only on Pro.
Share of failed transactions
The rule fires when, over a window, the share of direct transactions to the contract — sent to its address — that reverted is above the threshold. A window with no transactions is not a failure: the rule stays quiet. Example: "Revert 30% in an hour at a 2% norm".
Settings.
- Threshold — a share in percent, from 1 to 100.
- Window — 15 minutes, an hour, 6 hours or a day. An hour by default.
- Minimum transactions in the window — 20 by default. In a window with fewer transactions the share is not computed: the rule shows "not enough data", not 0%, and does not fire. Three failed out of five is not yet 60%.
Norm. The typical failed share over the last 7 days. The form shows "Norm: 2%", the 24-hour chart shows the norm band, the threshold dashes and hatching on windows with too few transactions.
Notification. The numbers are for the window the rule fired on, that is the last closed one:
- "Value: 30% (threshold: > 2%)"
- "Transactions: 12 of 40 failed"
- "Failed: 0xaa…01, 0xbb…02" — up to the three latest, links to the explorer
Receipt collection. A revert is visible only in transaction receipts. SmartAlert starts reading a contract's receipts when the first enabled transaction rule appears on it — from that moment, with no history before it. Until then the screen shows "This contract’s receipts aren’t collected yet" instead of the chart. The chart appears after one window, the norm once there are enough windows with transactions.
Networks. Transaction rules are not available on every network. On a network where receipt collection is off, the form does not open: the screen says "Transaction rules aren’t available on … yet".
Plan. Business and above. On Free and Pro the form is visible but locked. After a downgrade the rule is paused, with a "Business required, rule paused" notice.
Allowed senders
The rule fires when a contract function or event was called by an address that is not on your list. Example: upgradeTo(address) was called by someone other than your Safe.
Settings.
- What to watch — an event or a function of the contract. We recommend an event: it catches both a direct call and a call through a Safe or another contract. A function catches only direct calls: a call through a Safe will not get here, so pick the event this function emits.
- Allowed addresses — project addresses on the same network with one click, or any address typed in. Up to 50 addresses per rule. An empty list cannot be saved: with it every call would count as foreign.
A call is allowed if the list has whoever signed the transaction or the contract it was sent to. Add your Safe, and a call through it is allowed whichever owner executed it. Failed calls count too: a foreign attempt to call an admin function is worth knowing about.
Notification. Title "Called from a non-allowed address". The message has who called, the function or event, the contract and network, the allowed list, links to the transaction and the rule. A project address is shown by its name, a foreign one as a shortened address.
Receipt collection. The sender comes from transaction receipts, as for the share of failed transactions: reading a contract starts with the first rule on it, with no history before it. Same networks.
Plan. Business and above. On Free and Pro the form is visible but locked. After a downgrade the rule is paused.
Found a mistake or didn’t find an answer? Write to us