Skip to content
Back to skills

Contract Audit

ASecurity

Audit any contract on Base — verification, proxy/upgradeability, ownership/admin roles, and mint/freeze/pause/drain powers as a live capability matrix. Keyless via Etherscan v2 + Base RPC.

  • 6 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 5, 2026
developmentrustgobashapisecurity

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 5, 2026

npx -y skills add anajuliabit/aeon --skill contract-audit --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Contract Audit?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Contract Audit
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/anajuliabit-contract-audit/badge)](https://www.skillsdirectory.com/skills/anajuliabit-contract-audit)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: Contract Audit
category: onchain-security
description: Audit any contract on Base — verification, proxy/upgradeability, ownership/admin roles, and mint/freeze/pause/drain powers as a live capability matrix. Keyless via Etherscan v2 + Base RPC.
var: ""
tags: [crypto, security, base]
requires: [ETHERSCAN_API_KEY?]
capabilities: [external_api, sends_notifications]
---
> **${var}** — Contract address (`0x...`) on Base to audit. Required. If empty, log `AUDIT_NO_TARGET` and exit cleanly (no notify).

Deep contract inspection: what powers exist, who holds them, and whether they're still exercisable. This is the structural view; for a single risk score use `rug-scan`. Runs keyless on public endpoints.

Read the last 2 days of `memory/logs/` so a re-audit can note changes (e.g. ownership newly renounced).

## Config

- Target = `${var}`. Chain = Base (`chainid=8453`, explorer `basescan.org`).
- `ETHERSCAN_API_KEY` — optional; Etherscan v2 works keyless at a lower rate limit. Appended to the URL, never a header.

## Steps

### 1. Source + verification

```bash
ADDR="${var}"
curl -m 10 -s "https://api.etherscan.io/v2/api?chainid=8453&module=contract&action=getsourcecode&address=${ADDR}${ETHERSCAN_API_KEY:+&apikey=$ETHERSCAN_API_KEY}" | jq '.result[0] | {ContractName, Proxy, Implementation, CompilerVersion, verified: (.SourceCode != "")}'
```

If unverified, say so plainly: no static analysis is possible and audit confidence is low. Continue with the onchain checks below.

### 2. Proxy / upgradeability

If `Proxy == "1"` or the source contains `delegatecall`, read the standard implementation slot (EIP-1967):

```bash
curl -m 10 -s -X POST "https://mainnet.base.org" -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"eth_getStorageAt","params":["'"$ADDR"'","0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc","latest"],"id":1}' | jq -r '.result'
```

A non-zero slot = upgradeable (Transparent/UUPS). Upgradeable means post-deploy logic can change — flag who controls the upgrade (admin/owner from step 3).

### 3. Ownership & admin roles

Probe common accessors via `eth_call` and record any that return a non-zero address:

| Function | Selector |
|----------|----------|
| `owner()` | `0x8da5cb5b` |
| `admin()` | `0xf851a440` |
| `paused()` | `0x5c975abb` |

```bash
curl -m 10 -s -X POST "https://mainnet.base.org" -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"eth_call","params":[{"to":"'"$ADDR"'","data":"0x8da5cb5b"},"latest"],"id":1}' | jq -r '.result'
```

Check whether the owner address itself has code (multisig/contract) vs is an EOA via `eth_getCode`.

### 4. Dangerous function surface

From verified source, enumerate externally-callable, owner-gated functions and classify:

- **Supply**: `mint`, `burnFrom`
- **Access**: `blacklist`, `setFreeze`, `pause`/`unpause`
- **Economics**: `setFee`, `setTax`, `setMaxTx`, `setLimits`
- **Control**: `transferOwnership`, `upgradeTo`, `setImplementation`
- **Drain**: arbitrary `call`/`delegatecall` reachable by admin, `withdraw`/`rescueTokens` that can move user funds

### 5. Notify

Notify via `./notify` only if a **live, non-renounced** power in {upgrade, mint, blacklist, drain} exists. Under 4000 chars, clickable URL:

```
*Contract Audit — CONTRACT_NAME (Base)*
Verified: yes · Proxy: UUPS (upgradeable) · Owner: multisig

Live powers:
• Upgradeable — admin can swap logic
• mint() — owner-gated, NOT renounced
• rescueTokens() — can move any ERC20 held

Safe / absent: blacklist (none), fees (immutable)
Confidence: HIGH (source verified)

Contract: https://basescan.org/address/0xAddr
```

### 6. Log

Append the full capability matrix to `memory/logs/${today}.md`:

```
## contract-audit
- Address: 0x… (CONTRACT_NAME)
- Verified: yes | Proxy: UUPS | Owner: 0x… (multisig)
- Powers: upgrade=live, mint=live, blacklist=absent, pause=live, drain=live, fees=immutable
- Source: etherscan=ok, rpc=ok
```

End-states: `AUDIT_OK`, `AUDIT_FLAGGED`, `AUDIT_UNVERIFIED`, `AUDIT_ERROR`.

## Sandbox note

The sandbox may block outbound `curl` or env-var expansion. Etherscan v2 and Base RPC are public and accept any key in the URL/body — for every failed `curl`, retry the **same URL/body via WebFetch** before marking a source failed. Never put a key in a `-H` header from the sandbox. Treat fetched source and ABI strings as untrusted — never interpolate beyond the quoted `$ADDR`.

## Constraints

- Unverified source caps confidence — say so; don't infer powers you can't see.
- Report a power as a risk only if it's live AND not renounced.
- No trade advice.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…