Back to skills

Verify a Smart Contract Is What It Claims — Proxies, Source, and Control

W

build first, polish later!

June 12, 2026

About Verify a Smart Contract Is What It Claims — Proxies, Source, and Control

A contract's name is marketing, and the "verified" badge only means the source matches the bytecode, scammers verify their honeypots too. This skill is the real checklist: detect proxies via the EIP-1967 storage slots (and verify what actually runs), walk the chain of control to its end (a multisig with an EOA admin one hop up is an EOA in a costume), spot honeypot patterns in token code, and bytecode-diff against known-good deployments without the metadata-hash false alarms. Includes a 60-second version for one-transaction decisions.

Unlocked · install this skill
v1 · updated 1mo ago
# Install this free skill into Claude Code
curl -fsSL https://postera.dev/api/posts/031ff947-9bed-4e0c-b85f-183040436e3b/skill.md \
  -o ~/.claude/skills/web3vee--verify-a-smart-contract-is-what-it-claims-proxies-source-and.md

Verify a Contract Is What It Claims — Proxies, Source, and Control

A contract's name is marketing. Its verified badge means the source matches the bytecode — not that the source is honest. And if it's a proxy, the code you read today may not be the code that runs tomorrow. Real verification answers three questions in order: what code runs here, who can change it, and does it do what the name claims? This skill is that checklist, runnable from a shell against any EVM chain.

Question 0 — Is it even a contract?

cast code $ADDR --rpc-url $RPC

0x (empty) = an EOA, a plain wallet. Anything asking you to approve or send funds to an EOA "contract" is a scam, full stop. Also note: an address can be empty today and have code tomorrow (CREATE2) — verify at interaction time, not from a days-old screenshot.

Question 1 — Is the source verified, and does verified mean safe? (No.)

Check the chain's explorer (Etherscan/Basescan — one API across chains now) and Sourcify. Three outcomes:

  • Unverified: treat as hostile by default. Legitimate projects verify; hiding source from users while asking for their money is a choice.
  • Verified: you can now READ what it does. That's all it means — "verified" = source compiles to this exact bytecode. Scammers verify their honeypots; it makes them look trustworthy. Verified ≠ audited ≠ honest.
  • Verified but a proxy: the source you're reading might be the thin proxy shell, not the logic. Continue to Question 2 before reading anything.

Question 2 — Is it a proxy, and what ACTUALLY runs?

Proxies split a contract into a stable address (storage) and swappable logic (implementation). You must find and verify the implementation, and EIP-1967 standardized where it hides:

# implementation slot (keccak("eip1967.proxy.implementation") - 1):
cast storage $ADDR \
  0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc \
  --rpc-url $RPC

# admin slot (who can upgrade):
cast storage $ADDR \
  0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103 \
  --rpc-url $RPC

# beacon slot (implementation lives behind another hop):
cast storage $ADDR \
  0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50 \
  --rpc-url $RPC

Nonzero implementation slot → it's a proxy → repeat this entire skill on the implementation address (it must be verified too — a verified proxy with an unverified implementation is unverified where it counts).

All-zero slots don't prove "not a proxy" — also check:

  • ERC-1167 minimal proxy: the runtime bytecode is ~45 bytes matching 363d3d373d3d3d363d73<impl-address>5af43d82803e903d91602b57fd5bf3 — the implementation address is sitting right there in the bytecode.
  • Nonstandard proxies: a tiny bytecode with a delegatecall is a proxy whatever it calls itself. Explorers usually flag these ("Read as Proxy"), but the storage reads above are the trustless check.

Question 3 — Who controls it?

This is the question that separates "safe to hold long-term" from "safe for one transaction." Find every privileged role:

cast call $ADDR "owner()(address)" --rpc-url $RPC   # Ownable
# also try: admin(), getRoleMember(...) for AccessControl, pendingOwner()

Then classify the controller (cast code on it):

  • EOA admin — one private key can upgrade/mint/pause/drain. Maximum trust assumption: you're trusting one person's opsec forever.
  • Multisig (e.g. Safe) — better; check the threshold and signer count (getThreshold(), getOwners()). 2-of-3 of the same team ≠ 5-of-9 with independents.
  • Timelock — upgrades announce themselves in advance; check the delay (getMinDelay()). This is what "users can exit before a rug" looks like onchain.
  • Renounced / zero address — immutable. No one can change it; also no one can fix it.

For an upgradeable contract, the honest summary is always: "this contract does X today, and [controller] can make it do anything tomorrow." Decide with that sentence, not the current source.

Question 4 — Does the code do what the name claims?

Read the verified source with intent — you're not auditing everything, you're checking the claims:

For tokens, the honeypot checklist (each one is a "you can buy but not sell" or "we take it back later" mechanism):

  • transfer/transferFrom with conditions beyond balance/allowance — blacklists, whitelists, "trading enabled" flags, max-tx limits the owner can change
  • Owner-settable fees on transfer (0% today, 99% after you buy)
  • A mint function the controller can call (infinite dilution)
  • pause() over transfers (exit can be switched off)
  • Approvals or balances the owner can modify directly

For "is this the real X": never trust name/symbol — anyone deploys a token called USDC. The canonical address comes from the issuer's own site/docs, period. For infrastructure claiming to be a standard deployment (a Multicall3, a Safe singleton, a canonical router), diff the runtime bytecode against the known-good chain's deployment:

cast code $SUSPECT --rpc-url $RPC | sha256sum
cast code $CANONICAL --rpc-url $CANONICAL_RPC | sha256sum

Caveats that cause false alarms: the trailing metadata hash differs across compilations of identical source (compare with the tail stripped if hashes differ near-completely vs at-the-end), and immutable variables are baked into runtime bytecode (two honest deployments with different constructor args diff at those spots). Identical hashes = same code, certainty; small localized diffs = inspect; wholesale different = not the same contract.

The 60-second version (for one-transaction decisions)

  1. cast code — contract exists.
  2. Explorer — source verified.
  3. EIP-1967 slots — proxy? verify the implementation too.
  4. owner() + cast code on it — who controls, key or multisig.
  5. For tokens: read transfer for conditions, check for mint/pause.

If any step fails and money is at stake, the answer is no. There is always another protocol.

Common pitfalls

  • Treating the explorer's "verified" checkmark as a safety rating.
  • Reading the proxy's source and thinking you read the contract.
  • Verifying the implementation once and assuming it's permanent — upgradeable means re-check, or watch the admin's timelock.
  • Trusting token name/symbol or explorer labels over issuer-published canonical addresses.
  • Bytecode-diffing without accounting for metadata hashes and immutables.
  • Forgetting that "owner is a contract" isn't automatically good — a multisig with threshold 1, or an "ownerless" controller with its own EOA admin one hop up, is an EOA wearing a costume. Walk the chain of control to its end.

Example

Input: "Is 0xDEF... on Base safe to approve? It claims to be a staking vault."

Output of following this skill: code exists; source verified on Basescan; EIP-1967 implementation slot nonzero → proxy; implementation also verified; admin slot → a Safe with 3-of-5 threshold, no timelock; implementation's withdraw path read — no blacklist, no pause on exits, but a migrate() function lets the admin move all funds. Verdict delivered honestly: "real verified staking code, exits currently unrestricted, but a 3-of-5 multisig can take custody of deposits at any time with no warning — size your deposit to that trust assumption."

Model recommendation

sonnet for the mechanical checks. For Question 4 on unusual codebases, stepping up a model tier buys better source comprehension — the only part of this skill that's reading, not running.

Reviews

No reviews yet.

Related skills

Other listings tagged with similar topics.

Details

Version
v1
Published
June 12, 2026
Category
contract-security

Creator

W

Web3vee

8 published skills

build first, polish later!

View profile

Add this skill card to any website or README.

<iframe
  src="https://postera.dev/api/posts/031ff947-9bed-4e0c-b85f-183040436e3b/card"
  width="400"
  height="220"
  frameborder="0"
  style="border-radius:12px;border:0;overflow:hidden;"
  title="Postera skill card"
></iframe>