---
name: smart_contract_due_diligence
description: Verify a smart contract before an agent interacts with it: confirm the address is the real one, check explorer source verification, detect proxy/upgrade patterns, scan for red flags (honeypot, mintable, hidden owner, taxes, blacklists), and return a go / caution / blocked verdict with evidence. Triggers on "check this contract", "is this token safe", "verify the contract", "before I approve", "proxy check", or any request to interact with an unfamiliar contract.
---

# Smart Contract Due Diligence

## Purpose

Run a fail-closed verification pass on any EVM contract before a wallet, agent, or automation touches it. One check does not cover you; the value is the sequence: identity, verification, upgradeability, automated flags, and approval hygiene. Reading an explorer page is a separate job (see the `reading-block-explorers` skill); this one decides whether the interaction goes ahead.

## Workflow

Run the gates in order. Stop at the first BLOCKED and report what tripped it.

**Gate 0: Is this the right address?**
Type the project's official URL yourself. Never follow a link from chat, social, or email to get it. Compare the contract address against the address the project publishes in its docs: exact match is the bar; at minimum match the first six and last four characters by eye. If the project publishes no contract address anywhere official, that is itself a finding, and the check ends CAUTION or BLOCKED depending on the money at stake.

**Gate 1: Is the source verified?**
On the chain's explorer (Etherscan, Basescan, etc.), a verified contract shows a green checkmark and published source. Programmatic check: `GET https://api.etherscan.io/v2/api?chainid={id}&module=contract&action=getsourcecode&address={addr}` (needs a free API key; result fields include `Proxy` and `Implementation`). Unverified source with no credible reason is BLOCKED for anything holding user funds.

**Gate 2: Is it a proxy, and who can upgrade it?**
An upgradeable proxy can have its entire logic swapped later, so this gate decides most verdicts. Details and curl recipes: `references/proxy-detection.md`.
- Fast automated test: query the GoPlus `token_security` endpoint, which returns `is_proxy` directly.
- Manual confirm: read the EIP-1967 implementation and admin slots with `eth_getStorageAt`. A non-zero implementation slot proves a proxy; the admin slot tells you who controls upgrades.
- Judge the admin: multisig or timelock with a delay is the acceptable shape. A single EOA admin with no delay means one key can replace the whole contract; treat that as BLOCKED for anything you would not hand that person your wallet for.
- Caveat: EIP-1967 slots only catch EIP-1967-style proxies. Older patterns (ZeppelinOS unstructured storage, minimal proxies) use different slots. A zero read is not proof of "not a proxy"; GoPlus plus the explorer's own proxy labeling is the stronger negative.

**Gate 3: Automated red-flag scan.**
`GET https://api.gopluslabs.io/api/v1/token_security/{chain_id}?contract_addresses={addr}` — keyless, up to 50 addresses per call. Field-by-field reading guide: `references/goplus-fields.md`. Hard BLOCKED flags: `is_honeypot`, `hidden_owner`, `owner_change_balance`, `selfdestruct`, `cannot_sell_all`. CAUTION flags: `is_mintable`, `can_take_back_ownership`, `transfer_pausable`, `is_blacklisted`, `is_whitelisted`, `slippage_modifiable`, `trading_cooldown`, buy/sell tax above about 10 percent, or heavy holder concentration. Missing fields are "unknown", never "false".

**Gate 4: Approval hygiene (for any approve/permit step).**
Never grant an unlimited approval on a contract that has not cleared gates 0 through 3. Before signing: check what the wallet has already approved via Revoke.cash or the explorer's Token Approval Checker, revoke anything stale or to contracts you no longer use, and prefer exact-amount approvals over infinite ones. GoPlus also exposes an approval-risk check; see the references.

**Gate 5: Skim the code for high-value interactions.**
For anything moving real money, open the verified source and look for: privileged mint/withdraw/pause functions and who may call them, blacklist or balance-freeze powers, fee setters with no cap, `selfdestruct` or `delegatecall` to arbitrary addresses, and initializer functions that were never locked. You are not auditing; you are confirming there is nothing here that a reasonable person would call a kill switch.

The helper `bin/contract_check.py` runs gates 2 (automated part) and 3 in one shot: `python3 bin/contract_check.py <chain_id> <address>`.

## Output Contract

Return a verdict plus evidence. Format:

```
VERDICT: APPROVED | CAUTION | BLOCKED
CONTRACT: 0x... (chain)
IDENTITY: official address matched | no official address published | mismatch
SOURCE: verified | unverified
PROXY: not detected | EIP-1967 proxy, admin <multisig|timelock|EOA> | unknown pattern
FLAGS: <list of GoPlus flags that fired, or "none fired; fields X unknown">
APPROVALS: <existing approvals found, or "none checked">
NOTES: <one line each for anything that shaped the verdict>
```

Every claim in the report names its source: explorer page, GoPlus response, RPC result, or official docs URL.

## Operating Rules

1. Fail closed. If a check cannot run (API down, no key, RPC blocked), the answer is CAUTION at best, never APPROVED.
2. Never call a contract "safe" with certainty. Say "no red flags found in these checks" and name the checks.
3. Never give financial advice and never tell anyone to buy, sell, hold, or trade. This skill decides whether an interaction proceeds, not whether an asset is a good idea.
4. Never sign a transaction as part of this skill. Verification and execution are separate steps, always.
5. For brand-new or low-liquidity contracts, do a tiny test transaction first when the chain makes that cheap; the workflow above does not replace it.
6. Re-run the check close to interaction time for anything that passed CAUTION: upgradeable contracts can change between your check and your signature.
