The Test That Broke My 'Perfect' Contract

Published: (January 16, 2026 at 01:54 AM EST)
6 min read
Source: Dev.to

Source: Dev.to

Why Dev Tools Matter More Than Ever

The first time a test destroyed my “perfect” smart contract, it wasn’t a hacker. It was my own dev environment. I had just finished an AI‑assisted Solidity contract—clean code, no compiler warnings, a few happy‑path tests passing.

Then I switched frameworks, hit one command, and watched a fuzz test tear it apart. Same contract, same logic, different tools.

That’s when it clicked:

How you develop and test your contracts (Hardhat, Foundry, static analyzers) matters almost as much as what you write.

Why Dev Tools Matter Now

By now in this series you’ve:

  • Written and deployed simple contracts.
  • Seen how bugs like reentrancy can drain real money.
  • Watched AI generate “working” Solidity that still hides security traps.

The current reality:

  • Smart‑contract exploits still cost users hundreds of millions each year.
  • Security standards (e.g., OWASP Smart Contract Top 10, audit‑firm guides) push for tests, fuzzing, and static analysis, not just “it compiles.”

Most serious teams use a mix of:

  1. A dev framework – Hardhat / Foundry
  2. Automated tests – unit, integration, fuzz
  3. Static analysis tools – Slither, Aderyn

So if you’re learning Web3 today, you’re not just learning Solidity syntax. You’re learning a workflow.

Hardhat – The JavaScript Sidekick

Hardhat has been a default Ethereum dev tool for years and remains heavily used. Think of it as your full‑stack dev companion:

  • Write tests and scripts in JavaScript or TypeScript.
  • Deploy contracts, fork mainnet, run tasks, and hook into frontend tooling.
  • Huge plugin ecosystem (Ethers.js, OpenZeppelin, gas reporters, coverage, etc.).

Why beginners and product teams love Hardhat

  • If you come from Web2 or React, JS/TS tests feel natural.
  • Plays nicely with infra like MetaMask, Alchemy, Infura.
  • You can simulate real user flows using mainnet forking in local tests.

Weak spots

  • Tests live in JS/TS while contracts live in Solidity → context switch can slow some people.
  • Fuzzing and advanced testing are usually plugin‑based rather than built‑in.

Hardhat shines when

  • You’re building a dApp with a frontend.
  • You want rich tooling and integrations.
  • You think in “product flows” as much as “raw Solidity.”

Foundry – The Solidity‑Native Power Tool

Foundry has quickly become a favorite for Solidity‑heavy and security‑minded work. Think of it as your high‑performance testing and security rig:

  • Write tests directly in Solidity.
  • Run them with forge test.
  • Built‑in fuzzing, invariant tests, cheatcodes, and blazing‑fast compile times.

Key advantages

FeatureBenefit
SpeedBenchmarks show Foundry compiling and running tests several times faster than traditional JS‑based setups.
Solidity‑firstNo JS/TS layer; your tests are contracts. Stay in one language and think like the EVM.
Security‑friendlyFuzzing and invariants are first‑class, exactly what modern security guides recommend.

Why this matters after the previous articles

  • When reviewing AI‑generated contracts, fuzz tests can hit weird inputs you’d never think of.
  • When worried about reentrancy or logic bugs, invariants let you assert things like “total balances never go negative, no matter the inputs.”

Foundry shines when

  • You care deeply about Solidity correctness and security.
  • You’re comfortable living mostly in Solidity.
  • You want to iterate on tests and contracts fast.

So… Hardhat or Foundry?

For most builders the honest answer is often: both, depending on the job.

Mental model

ToolFocus
HardhatProduct & integration – JS/TS tests, mainnet forking, plugin ecosystem, frontend/devops integrations.
FoundrySolidity & security – Fast compile/test loop, Solidity‑only tests, built‑in fuzzing & invariants.

You don’t have to marry one tool forever. A common workflow:

  1. Prototype & core‑logic testing with Foundry.
  2. Deployment scripts, mainnet forks, and frontend integration with Hardhat.

For this 60‑day journey

  • If you’re just getting comfortable with Solidity, starting with Foundry tests can actually teach you more Solidity faster.
  • If you’re more comfortable in JS/TS, Hardhat is a gentle on‑ramp into smart contracts.

The real mistake isn’t picking the “wrong” framework.
It’s not using any framework seriously and relying only on Remix + hope.

Where Slither and Aderyn Fit

On the last article, a medium follower, MihaiHng commented:

“Besides manual review checking for the CEI pattern to be respected, there are some static analysis tools that are very helpful, like Slither, Aderyn.”

He’s absolutely right. Manual review + CEI is important, but modern security culture assumes you will miss things. That’s where static analyzers come in.

Slither (Trail of Bits)

  • One of the most widely used Solidity static analysis tools.
  • Detects common vulnerabilities (reentrancy, access‑control issues, dangerous patterns) quickly.
  • Integrates nicely into CI and works with both Hardhat and Foundry projects.

Aderyn (Cyfrin)

  • A modern static analyzer focused on Solidity projects.
  • First‑class support for Foundry and Hardhat layouts.
  • Generates reports in JSON/Markdown/SARIF and plugs into VS Code for in‑editor feedback.

Realistic workflow

  1. Write tests in Hardhat or Foundry.
  2. Run fuzzing/invariants for deeper coverage.
  3. Also run Slither/Aderyn to catch patterns humans and tests might miss.

A Dev Workflow You Can Copy

Here’s a lightweight process you can actually run on your next contract:

1. Prototype

  • Use AI (carefully) plus your own edits to draft the Solidity.
  • Keep contracts small and focused.

2. Pick a framework

  • If you’re in JS land:

    npx hardhat init
    # write JS/TS tests
  • If you’re Solidity‑first:

    forge init
    # write Solidity tests

3. Write tests

  • Unit tests for happy‑path behavior.
  • Fuzz tests / invariants for edge cases.

4. Run static analysis

# Hardhat example
npx hardhat run scripts/deploy.ts
slither .

# Foundry example
forge test
aderyn .

5. CI integration

  • Add a GitHub Actions workflow that runs forge test && slither . or hardhat test && slither ..
  • Fail the build on any finding.

6. Deploy

  • Use Hardhat scripts for frontend‑ready deployments, or Foundry’s forge create for quick mainnet forks.

Solidity land: Foundry project, Solidity tests

Write basic tests

  • Happy‑path unit tests – deposits, withdrawals, state changes.
  • A few “annoying user” cases (zero values, big values, repeated calls).

Add fuzzing / invariants

  • Foundry – use built‑in fuzz tests and invariants.
  • Hardhat – add fuzzing via plugins or external tools if needed.

Run static analysis

  • Slither – quick scan for known bug patterns.
  • Aderyn – extra detectors plus better integration with modern stacks.

Only then think about testnet / mainnet

After tests + fuzzing + static analysis are green, deploy to a testnet (e.g., Sepolia).

  • Share the address with your community for more eyes.

TL;DR

  • Hardhat = product‑centric, JS/TS‑friendly, rich plugin ecosystem.
  • Foundry = Solidity‑centric, ultra‑fast, security‑first.
  • Slither & Aderyn = static analysis safety nets.

Mix and match to suit the task, and never rely on a single tool. Happy building!

What’s Coming Next

Today’s article zoomed out and asked:

“How do real‑world teams actually develop and test smart contracts?”

Tomorrow we’ll zoom back in and do this end‑to‑end on a real contract:

  1. Take a small AI‑generated Solidity contract.
  2. Wrap it in a Foundry project.
  3. Add a handful of tests, then fuzzing and an invariant.
  4. Run Slither or Aderyn once and see what they catch before any testnet deploy.

Think of today as the map of the territory.
Tomorrow, we’ll walk a full path through it together, step by step.

Resources to Go Deeper

  • Solidity Docs — Security Considerations – Official language docs explaining why external calls are dangerous and how to structure state changes safely.
  • ConsenSys Diligence — Smart Contract Best Practices – Classic reference for attack patterns, checks‑effects‑interactions, and common pitfalls.
  • OpenZeppelin Contracts — ReentrancyGuard – The de‑facto standard implementation of a reentrancy lock; perfect for understanding how to actually use the pattern.
  • Foundry Documentation – Complete guide to installing, testing with fuzz, invariants, and cheatcodes.

Follow the series on

Join the conversation on Telegram: Web3ForHumans and let’s build together.

Back to Blog

Related posts

Read more »

Web3 store

Overview I wrote and deployed a demo Web3 store using Solidity and ethers.js as a learning exercise. The original tools recommended by an older book web3.js, T...