Attack surface summary
How many functions are reachable by anyone, gated to an owner, gated to a role, accept ETH, or only read. The first number that matters is how much is open.
Paste a contract and see its attack surface mapped: who can call what, what a privileged key controls, which external systems you depend on, and what an attacker would actually be aiming for. Runs entirely in your browser. The source is never uploaded.
A vulnerability scanner tells you it found something. It can be wrong twice over: flagging safe code, and staying silent on a real bug.
A threat model makes a narrower claim: here is what your contract exposes, and to whom. That a path exists does not mean it is exploitable. Your access checks may be entirely correct. What the model gives you is the question list: should anyone be able to reach this, and should one key hold this much.
That framing is why threat modelling comes first in a real review. You cannot judge whether a control is sufficient until you know what it is protecting and who it is protecting it from.
It parses your source: function visibility, modifiers, what each body touches, external calls, and state declarations. It does not compile, resolve inheritance from imported files, follow values across contracts, or model economics. A function inheriting onlyOwner from a base contract in another file will look unguarded here.
Five sections, each answering a question an auditor asks in the first hour of a review.
How many functions are reachable by anyone, gated to an owner, gated to a role, accept ETH, or only read. The first number that matters is how much is open.
Drain value, seize ownership, replace the logic, destroy the contract, inflate supply, freeze funds, alter parameters, each shown with the functions that reach it, and whether that path is open to anyone or needs a key.
What a compromised owner or role key can do, in plain terms. This is the section most projects have never written down, and the one users ask about after a rug.
Every externally reachable function, grouped by who can call it, with the capability detected in its body and its line number. Read-only functions are separated so the open surface reads honestly.
Oracles, interface calls and delegatecall targets: every place your contract depends on code or data you do not control. Their failure modes become yours.
The state worth attacking: balance ledgers, control addresses, protocol-wide accounting. What an attacker is actually trying to reach.
Thirteen known-bad patterns checked against your source: reentrancy ordering, access control, oracle manipulation, signature replay. Where the threat model asks what is exposed, the scanner asks what is already broken.
Twelve worked explanations with vulnerable code, the fix, a test that catches it, and a stepped animation of the attack running.
The model shows you the questions. A named auditor answers them: whether each control is actually sufficient, and what the tool could never see.
If you send us a contract, the model above is roughly what we build by hand in the first hour anyway. Running it yourself first means the conversation starts at “is this control sufficient” rather than “what does this contract do”.
It also tends to surface the uncomfortable question early: how much does one key control, and is that what your users think they signed up for.