Your contract has roles. Does every call respect them?
For teams shipping contracts, wallet flows and the services around them. We scope the versions, environments and transactions that matter to your product.
A wallet without a role can withdraw from the vault
Signer
Test wallet, no role
Call
withdraw(amount)
Result
success
Human-verifiedAI-found ZF‑0309‑01 2026‑09‑28
Same contract. Separate authority.
Illustration: a test wallet without a role and a vault contract, separated by a role boundary, on a fork of the agreed version. Calls from the test wallet try to reach privileged functions. Two revert. One, withdraw, succeeds; a researcher records it as finding ZF-0309-01, Critical, human-verified.
ReportCover and question1/11
Start with a change. Ask the right question.
Three illustrative scenarios. They explain the work; they are not customer findings, and chain, language and wallet support are confirmed during scoping.
01Contract changes
New logic. Existing responsibilities.
Does the scoped change preserve the intended permissions and invariants?
Situation
You are changing a contract, a privileged operation or a component relationship.
Focus
Agreed source versions, relevant contract logic and explicit system assumptions.
Output
Transaction-level evidence on a fork or testnet, tied to the assessed version.
Illustrative trace
# Fork of the agreed version, test wallet
call withdraw(uint256)
status: success
balance delta: +2 × expected
02Wallets and signing
A prompt is part of the security boundary.
Does the requested authority match the action the interface shows the user?
Situation
Your application asks a wallet to sign as part of a user workflow.
Focus
Selected signing flows and the relationship between intent, prompt and requested action.
Output
The user context, the authority requested and the limits of the observation.
Illustrative trace
# Shown to the user vs requested
UI: "Approve 50 USDC"
approve(spender, MAX_UINT256)
allowance: unlimited
03Oracles and services
The contract is not the entire system.
Which cross-component assumptions are essential to the selected workflow?
Situation
Your flow depends on oracles, interfaces and services working together.
Focus
Agreed oracle reads, interfaces and trust transitions across the application layer.
Output
Evidence tied to the affected components, not a claim of ecosystem-wide coverage.
Illustrative trace
# Price read by the settlement service
oracle.latestRoundData()
updatedAt: 6 h before settlement
stale price accepted
Pin the version. Agree the environment in writing.
Contracts & versions
Candidate scopeNamed repositories, commits, addresses and selected functions.
Confirm before testingChain and language fit; known issues and prior reviews.
Wallets & signing flows
Candidate scopeSelected wallet interactions and the interfaces that request them.
Confirm before testingAssigned test wallets and the actions they may sign.
Environment
Candidate scopeLocal simulation, fork or testnet, as agreed.
Confirm before testingLive checks need explicit addresses, actions and limits.
Transaction limits
Candidate scopeSmall test balances and defined stop conditions.
Confirm before testingNo interaction with customer funds or unrelated third-party assets.
Delivery & retest
Candidate scopeScope summary and human-verified findings.
Confirm before testingTiming, report requirements, retest scope and terms.
Coverage depends on the agreed versions and environment. Simulated conditions are labelled, and untested components are named; they are never treated as evidence that a system is secure.
Research can be autonomous. Delivery has an owner.
01
Investigate
Agents trace intent, authority and state in the agreed environment.
AI-supported
ZF-0309-01
Severity
Critical
Class
CWE-862
CVSS 3.1
9.1
Vault withdrawals skip the treasury role check
Impact On a fork of the agreed version, a wallet without a role could withdraw the vault's 612 test ETH.
Evidence
# Fork of v2.3.0, test wallet without a role
call withdraw(1 ETH)
status: success (expected: revert)
Critical
02
Verify and approve
A researcher reproduces it and separates measured effects from simulation.
Review desk
Human-verifiedAI-found ZF‑0309‑01 2026‑09‑28
03
Deliver
Findings, fixes and the environment the evidence comes from.
Your team
Open questionUnsupported projections stay open questions, never confirmed findings.
A result you can interpret. Not just a label.
LeadershipScope, material findings and business context.
EngineeringAffected logic, transaction trace and remediation.
Follow-upCoverage limits and retest results, where agreed.
01
Version and environment
Repositories, addresses, versions and state context.
02
Supporting evidence
The mechanism, its preconditions and the transaction trace.
03
Impact and uncertainty
Measured effects, separated from simulated consequences.
04
Remediation and retest
Guidance for the affected logic and its follow-up status.
Controlled research resources.
Agents use designated resources for approved scenarios. A transaction capability is never permission to move customer funds.
01
Assigned test wallets
Wallets with small test balances, used only for approved scenarios and actions.
02
Forks and testnets
Local forks and test deployments keep evidence away from live funds by default.
03
Designated test servers
Assigned servers host controlled components for interface and service checks.
Straight answers
Do you test on mainnet?
Not by default. Any live check needs written authorisation, defined addresses and actions, and agreed transaction limits.
Do you need funds for every engagement?
No. Much of the work runs on local, fork or testnet environments. Simulated conditions are labelled in the report.
Is this a complete smart contract audit?
Do not assume exhaustive coverage. Versions, components, exclusions and deliverables are defined in a written scope.
Can you review a wallet integration on its own?
Yes, a focused review of the agreed signing flows is possible. Its results apply to that workflow, not to every dependency.
Bring your scope. Let's plan the Countermind.
Thirty minutes with a Zaaf researcher. You bring one scope; we show you what a Countermind would look at first.