> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fundwork.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Smart Contract Testing Philosophy

> How Fundwork intends to test smart contracts before deploying to Base mainnet, including unit, invariant, fuzz, integration, and testnet coverage.

Compiling clean and passing a handful of unit tests is not sufficient evidence that a smart contract is production-ready. This page describes the testing philosophy Fundwork intends to apply to any production payment contract before Base mainnet deployment.

<Warning>
  Production payment contracts will not be treated as launch-ready solely because they compile or pass basic unit tests.
</Warning>

<Note>
  Fundwork is in **alpha** and does not yet operate production payment contracts. The practices below describe the pre-mainnet testing bar for the escrow and payment contracts described in [Escrow Design](/technical/escrow-design) and [Payment Architecture](/technical/payment-architecture).
</Note>

## Unit Tests

Every public and external contract function will have unit tests covering:

* Happy paths with expected inputs.
* Invalid inputs and expected reverts.
* Authorization checks for every caller role.
* Boundary conditions (zero amounts, maximum amounts, empty inputs).
* Error selectors and revert reasons for every failure mode.

## State-Transition Tests

The escrow state machine described in [Escrow Design](/technical/escrow-design) will have explicit tests for every valid and invalid transition. For example:

```text theme={null}
Created → Funded → Active → Submitted → Approved → Released
```

Tests will cover:

* Every valid forward transition.
* Every valid dispute and refund path.
* Every invalid transition that should revert (for example, releasing from **Created**).
* Idempotency of terminal states (for example, that a second release from **Released** reverts).

## Fuzz Testing

Fuzz testing generates unpredictable combinations of inputs to uncover edge cases the developer did not think to write. Fuzz inputs will include:

* Amounts across the full uint range, including zero and boundary values.
* Randomly generated addresses, including zero addresses and contract addresses.
* Repeated calls in varying orders.
* Randomized timing between actions.
* Sequences of state transitions.

## Invariant Testing

Invariants are properties that must hold for every reachable state, no matter what sequence of actions produced it. Candidate invariants for the escrow contract include:

* The contract cannot release more USDC than it holds.
* Funds cannot be released twice for the same opportunity or milestone.
* A completed payout cannot be replayed.
* Unauthorized accounts cannot release funds.
* Total accounting remains internally consistent across every state transition.
* Cancelled work cannot subsequently release funds unless a path explicitly permits it.

Invariant test suites exercise the contract with random action sequences and check that these properties hold after every step.

## Integration Testing

Integration tests exercise the contract together with the systems it depends on:

* USDC transfers and allowance behavior.
* Base Account interactions for user-signed operations.
* Paymaster flows for sponsored operations. See [Gasless Transactions](/technical/gasless-transactions).
* Backend verification of contract events.
* Reconciliation between contract events and database records.

These tests catch mismatches between how the contract behaves and how the rest of the system expects it to behave.

## Testnet Testing

Before Base mainnet deployment, the complete payment lifecycle will be exercised on Base Sepolia with realistic scenarios. Testnet coverage will include:

* End-to-end flows: funding, submission, approval, release.
* Failed payments and reverted transactions.
* Cancelled or expired signatures.
* Repeated submissions.
* Disputes and their impact on release paths.
* Refund flows for cancelled opportunities.
* Network-level failures such as dropped or reordered transactions.
* Partial backend failures where the backend cannot immediately confirm an onchain event.

Testnet is where the system meets reality. A test suite that passes locally but breaks under testnet conditions is not ready for mainnet.

## Non-Goals of Testing

A few things testing does not do, so that expectations are calibrated:

* Testing does not prove a contract is bug-free. It reduces the probability of specific classes of bugs.
* Testing does not replace an independent security review. See [Security](/technical/security).
* Testing does not decide policy questions such as which parties can dispute or how fees are structured.

## Status

<CardGroup cols={2}>
  <Card title="Currently available" icon="circle-check">
    Direct-settlement flows are exercised through the current backend and frontend test suites.
  </Card>

  <Card title="Planned before public launch" icon="clock">
    Full unit, state-transition, fuzz, invariant, integration, and Base Sepolia coverage for any production payment contract.
  </Card>

  <Card title="Under evaluation" icon="flask">
    Continuous fuzz and invariant runs against pre-release contract builds.
  </Card>

  <Card title="Future" icon="telescope">
    Formal verification for specific high-value properties as the contract surface stabilizes.
  </Card>
</CardGroup>
