# see-through

Contract Registration & Autodiscovery

When you register a contract with ChainAlert, we resolve its ABI from public verification services, detect proxy patterns, discover interesting storage slots by recompiling verified source code, and analyze the contract's traits to suggest relevant detection templates. This document explains each step transparently.

Contract Resolution

Contract resolution takes an address and network, fetches the contract's ABI from public verification services, and caches it for all organizations.

contract-resolver — pipeline

$ resolve --address 0xa0b8...eb48 --network ethereum

1.
NormalizeConvert address to lowercase for consistent storage
2.
Cache CheckQuery contracts table — if found, return immediately (no external calls)
3.
Etherscan V2Fetch ABI + source code via unified API (works for all EVM chains)
4.
Sourcify FallbackIf Etherscan fails, try Sourcify's decentralized repository
5.
StoreUpsert into global contracts table (shared across all orgs)

>resolved: FiatTokenV2_2 (verified) — 83 ABI entries

Etherscan V2 API — a unified endpoint that works for Ethereum, Arbitrum, Base, and Polygon using a single chainid parameter

Only verified contracts — if the source isn't verified on Etherscan or Sourcify, registration fails. This is deliberate — unverified contracts lack the ABI needed for detection

Two-table architecture — global contracts table holds ABI data (shared), per-org org_contracts table holds labels, tags, and notes (private)

Storage Layout Autodiscovery

After resolving a contract, ChainAlert asynchronously recompiles the verified source code using the exact Solidity compiler version to extract the storage layout. It then filters for interesting variables — governance, security, and financial parameters — and makes them available for detection setup.

layout-discovery — pipeline

$ discover-layout --contract FiatTokenV2_2

1.
Parse SourceHandle 3 Etherscan formats (double-braced JSON, standard JSON, plain)
2.
Load CompilerDownload exact solc WASM version used during verification (cached)
3.
CompileRequest only storageLayout output (fast, no bytecode)
4.
FilterKeep variables matching keywords: owner, admin, fee, paused, implementation, balance, threshold...

>discovered 4 slots: _owner (slot 0), _paused (slot 0:20), _totalSupply (slot 1), _fee (slot 3)

Fire-and-forget — discovery runs in the background after resolution (typically 2–10 seconds)

Solidity only — Vyper and other languages are detected and marked as unsupported

Keyword-based filtering — heuristic, not semantic. Variables are filtered by name, so a variable called criticalParam won't match, but feeLimit will

Trait Detection

After registration, ChainAlert analyzes the contract's ABI to detect common patterns and makes targeted on-chain reads to gather live state.

TraitDetection MethodSuggested Templates
ERC-20transfer, balanceOf, totalSupply, decimals in ABILarge Transfer, Fund Drainage, Balance Low
Ownableowner() in ABI + on-chain readOwnership Transfer
AccessControlhasRole, grantRole, revokeRole in ABIRole Change
Pausablepaused, pause, unpause in ABIPause State Change
Gnosis SafegetOwners, getThreshold, nonce in ABIMultisig Signer Change
Proxy (UUPS)upgradeTo in ABI or ERC-1967 slotProxy Upgrade (Event + Slot)
ERC-721ownerOf, tokenURI, safeTransferFrom in ABICustom Event
ERC-1155balanceOfBatch, safeBatchTransferFrom in ABICustom Event

On-chain reads — for detected traits, we call owner(), paused(), token metadata, and balance functions to populate the contract dashboard

Proxy detection — when the ERC-1967 implementation slot contains a non-zero address, the contract is marked as a proxy and the implementation address is stored

Template suggestions — detected traits are used to suggest relevant detection templates during setup, reducing configuration friction

Known Limitations

Only verified contracts are supported. Unverified contracts cannot be registered or monitored.

Storage layout discovery only works for Solidity contracts. Vyper, Yul, and other languages are not supported.

Layout discovery is fire-and-forget — check the layoutStatus field to know when it completes.

The keyword filter is heuristic, not semantic. Review discovered slots and add custom monitors for variables that don't match keywords.

For proxy contracts, layout discovery runs on the proxy source, not the implementation. The implementation may need separate resolution.

Trait detection uses function name matching, not signature parsing. False positives are rare but possible.

Related Documentation

Detection Templates — how each template uses resolved ABIs and discovered slots

Storage Monitoring — deep dive into storage slot polling mechanics

Supported Chains — which chains support contract resolution