Skip to main content
This guide covers testing the Flash Loan Router contracts using Foundry’s Forge testing framework.

Running Tests

The project uses Forge for comprehensive smart contract testing.

Basic Test Execution

Run all tests in the project:
This command:
  • Compiles all contracts
  • Executes all test files in the test/ directory
  • Generates gas benchmarks (saved to snapshots/ folder)
  • Reports test results with gas usage

Verbose Output

For detailed test execution information:
Use -vv to see console.log() output from your tests, which is helpful for debugging.

Excluding E2E Tests

Some tests require internet connectivity to interact with live networks. To run tests without these end-to-end tests:
This is useful for:
  • CI/CD pipelines without network access
  • Faster local development iterations
  • Running tests without external dependencies
E2E tests validate integration with real flash loan providers like Aave and Maker, so they should be run before production deployments.

Test Organization

Tests are typically organized in the following structure:

Running Specific Tests

By Test File

By Test Contract

By Test Function

Combined Filters

Gas Benchmarking

The repository includes automated gas benchmarking for different flash loan providers.

Generate Benchmarks

Gas snapshots are automatically generated when running tests:
Benchmark data is saved to the snapshots/ directory:

View Gas Report

Generate a detailed gas usage report:
Example output:

Update Snapshots

To update gas snapshots after contract changes:
Review gas snapshot changes carefully before committing. Significant increases may indicate performance regressions.

Test Configuration

Test settings are configured in foundry.toml:

Transaction Isolation

The isolate = true setting ensures:
  • Each function call in a test is an independent transaction
  • Transient storage is cleared between calls
  • More accurate simulation of real-world behavior
This is particularly important for testing transient storage features. See Foundry issue #6908 for details.

Writing Tests

Test Structure

Foundry tests use Solidity and follow this pattern:

Common Test Patterns

Continuous Integration

For CI environments, use the CI profile with strict settings:
The CI profile (defined in foundry.toml):

Test Coverage

Generate test coverage reports:
Aim for >90% code coverage, with 100% coverage for critical security functions.

Debugging Tests

Debug Mode

Run a specific test in debug mode:
This opens an interactive debugger where you can:
  • Step through transactions
  • Inspect state variables
  • View stack traces
  • Examine memory and storage

Console Logging

Add debug output to your tests:
Run with -vv to see console output:

Common Testing Scenarios

Unit Tests

Test individual contract functions in isolation:
  • FlashLoanRouter authentication
  • Borrower flash loan triggers
  • Approval management
  • Access control

Integration Tests

Test contract interactions:
  • Router + Borrower coordination
  • Multiple flash loans in sequence
  • Settlement execution flow
  • Token transfers

E2E Tests

Test with real protocols:
  • Aave flash loans
  • Maker flash mints
  • CoW Protocol settlements
  • Multi-network deployments

Security Tests

Test security properties:
  • Reentrancy protection
  • Access control validation
  • Flash loan repayment
  • Invariant testing

Best Practices

  1. Test organization: Group related tests in descriptive contracts
  2. Clear test names: Use descriptive names like testFlashLoanRevertsWithInsufficientApproval
  3. Setup isolation: Each test should be independent and reproducible
  4. Edge cases: Test boundary conditions, zero values, and maximum amounts
  5. Error cases: Test expected failures with vm.expectRevert()
  6. Gas optimization: Monitor gas usage with benchmarks
  7. Documentation: Comment complex test scenarios

Troubleshooting

Common causes:
  • Different Forge versions
  • Network-dependent tests not excluded
  • Non-deterministic behavior (use fixed seeds)
  • Missing environment variables
Solution: Use FOUNDRY_PROFILE=ci locally to reproduce CI environment.
Increase the gas limit for tests:
Or in foundry.toml:
The isolate = true setting handles transient storage. If you encounter issues:
  1. Verify isolate = true in foundry.toml
  2. Update to latest Forge version
  3. Check Foundry issue #6908

Next Steps

Deployment Guide

Deploy tested contracts to networks

Development Setup

Set up your development environment
Last modified on March 4, 2026