Files
papers/lux-fuzz-testing-methodology/sections/03-foundry-fuzz-testing-for-smart-contracts.tex
zeekay abf99d05fc papers: reorganize into per-paper dirs, add Antje Worring as co-author
Restructured from flat .tex/.pdf files into per-paper subdirectories.
Added Antje Worring as co-author on all papers.
Synced PDFs to pdfs/ for download site.
2026-04-18 21:50:07 -07:00

56 lines
2.1 KiB
TeX

\section{Foundry Fuzz Testing for Smart Contracts}
\subsection{Random Fuzz Testing}
Foundry's fuzz mode generates random inputs for each test parameter:
\begin{lstlisting}[language=Solidity,caption={Foundry fuzz test with bound}]
function testFuzz_swapNeverIncreasesK(
uint256 amountIn
) public {
amountIn = bound(amountIn, 1, pool.reserve0() / 2);
uint256 kBefore = pool.reserve0() * pool.reserve1();
pool.swap(amountIn, 0, address(this));
uint256 kAfter = pool.reserve0() * pool.reserve1();
assertGe(kAfter, kBefore);
}
\end{lstlisting}
Key functions:
\begin{itemize}[nosep]
\item \texttt{bound(x, min, max)}: Clamps \texttt{x} to $[\texttt{min}, \texttt{max}]$.
Unlike \texttt{vm.assume}, this does not discard inputs---it transforms them.
\item \texttt{vm.assume(cond)}: Discards the input if \texttt{cond} is false. Use
sparingly: too many rejections waste fuzz cycles.
\end{itemize}
\subsection{Stateful Invariant Testing}
Invariant testing is the most powerful fuzz technique for smart contracts. Foundry
generates random sequences of function calls (actions) and checks invariants after each
action.
The key insight: bugs often require specific sequences of operations. A deposit followed
by a withdraw is fine; a deposit, a price change, and then a withdraw may violate an
invariant. Invariant testing explores these sequences.
\subsection{Coverage Metrics}
\begin{lstlisting}[language=bash,caption={Foundry coverage report}]
$ forge coverage
| File | % Lines | % Stmts | % Branch | % Funcs |
|--------------------|---------|---------|----------|---------|
| src/Pool.sol | 96.2% | 94.8% | 91.3% | 100% |
| src/Vault.sol | 93.7% | 92.1% | 88.9% | 97.4% |
| src/Bridge.sol | 95.1% | 93.4% | 90.2% | 100% |
| src/Token.sol | 98.3% | 97.6% | 95.1% | 100% |
\end{lstlisting}
We require $\geq$85\% branch coverage. Uncovered branches must be justified (e.g.,
unreachable error paths, platform-specific code).
%% ============================================================