# What I Learnt From My First Smart Contract Audit

I'm learning smart contract security through [Cyfrin Updraft's Security course](https://updraft.cyfrin.io/courses/security). This was audit #1: a small Solidity contract called **PasswordStore**. The full write-up, my notes, and every `@AUDIT` comment live in [my security repo](https://github.com/moayaan1911/security). Nothing sanitised.

---

## What even is a smart contract audit?

It's a security review of a codebase. Experts read the code, test it, and report what could go wrong. Crucially it is **not a guarantee**: it reduces risk, it doesn't eliminate it. I learnt that in Section 2, and it reframed everything that came after.

---

## Getting started: onboarding a real client

Before reading a single line, you onboard. You ask for the repo, the scope, the commit hash, build/test commands, and basic contract metrics.

The commit hash is the important one: it fixes *exactly* what's in scope. Anything the team commits after it is unaudited.

My first real lesson came here. The README inside my checkout listed one hash, but the client's **latest** README listed a newer one, because the README itself had been updated in a later commit. The copy sitting inside your own checkout can be outdated. Always confirm the scope hash against the client's latest README, not the one you're staring at.

---

## The tools

Two stages, and one detour.

**Sizing.** I ran `cloc` and the Solidity Metrics VSCode extension to measure the contract *before* reading it: **20 nSLoc, complexity 10**. That drives how long a review takes and what you charge for it.

**Reporting.** The client's README suggested `pandoc` + LaTeX with the eisvogel template. I installed pandoc and converted the logo, then found out the full LaTeX stack is roughly **5GB** and fiddly for a first attempt. I switched to an HTML-friendly template using [claude](https://claude.ai/) instead and shipped the same report at a fraction of the setup cost.

Lesson: perfect tooling is worthless if it stops you from finishing.

---

## What I found

Findings get severity ratings:

- **High:** breaks the protocol completely, risks user funds, likely to happen
- **Medium:** partially breaks it, may impact funds
- **Low:** doesn't break it, but still needs fixing
- **Informational:** a note, not a vulnerability

> ⚠️ **Spoiler warning:** PasswordStore is a Cyfrin course exercise. If you're working through it yourself, skip ahead to *Shipping it*.

The headline finding was that the contract *pretends* to be private:

```solidity
// @notice This function allows only the owner to set a new password.
function setPassword(string memory newPassword) external {
    s_password = newPassword;
    emit SetNetPassword();
}
```

The comment says "only the owner". There is no owner check. **Anyone can overwrite the password.**

The second High: even with access control fixed, the password is stored in **plaintext on-chain**. On-chain state is public. I proved it by reading the storage slot directly and decoding it back into `myPassword`.

Final tally: **H-1, H-2 (High)** and **I-1, I-2 (Informational)**.

---

## Shipping it

A finding report is the deliverable, not your notes. My private `audit_notes.md` never left my machine. The client got a structured report written against a fixed template.

📄 [**Read the final audit report (PDF)**](https://github.com/moayaan1911/security/blob/main/03-first_audit_passwordstore/audit_data/report.pdf)

---

## What I'd do differently

1. **Verify the scope hash against the client's latest README first**, not the copy inside my checkout.
2. **Check dependencies before anything else.** The client repo shipped with empty submodules, so nothing built until I ran `git submodule update --init --recursive`.
3. **Not fight the tooling.** Five minutes into LaTeX pain I should have switched, not an hour.
4. **Keep tagging findings as I go.** The `@AUDIT` comments meant the report almost assembled itself.

---

## Final thoughts

An audit isn't about being clever. It's about being systematic: scope it, size it, read it, tag what's wrong, rate the severity, and ship something the client can actually act on.

Two High findings in a 20-line contract was a good reminder that small code is not safe code.

---

---

*Drafted with DeepSeek Harness; all experiences, findings and opinions are my own.*

## About the Author

![](https://cdn.hashnode.com/uploads/covers/633f2b4c6971ffceb981eb89/b83f4561-ad65-4b20-9023-8e76707f7b86.png align="center")

Assalamualaikum guys! 🙌 This is Mohammad Ayaan Siddiqui (♦moayaan.eth♦). I'm a Full Stack Blockchain Developer, Crypto Investor and MBA in Blockchain Management with 2 years of experience rocking the Web3 world! 🚀 I've worn many hats:

- Research Intern at a Hong Kong-based firm 🇭🇰
- Founding Engineer at a Netherlands-based firm 🇳🇱
- Full Stack Intern at a Singapore-based crypto hardware wallet firm 🇸🇬
- Blockchain Developer at a US-based Bitcoin DeFi project 🇺🇸
- PG Diploma in Blockchain Management from Cambridge International Qualifications (CIQ) 🇬🇧
- MBA in Blockchain Management from University of Studies Guglielmo Marconi, Italy 🇮🇹

Let's connect and build something epic! Find me at [moayaan.com](https://moayaan.com) 🌐 or on X [@moayaan1911](https://x.com/moayaan1911)
