Skip to main content

Testing Frameworks

Comprehensive Testing Approach

Testing is essential for validating smart contract security and correctness. We employ a variety of testing frameworks and methodologies to provide comprehensive coverage and find vulnerabilities that might be missed by static analysis.

Core Testing Frameworks

Hardhat

Description: Hardhat is a development environment for Ethereum software, designed for professional developers. It features built-in testing and debugging capabilities.

Use Cases:

  • Unit and integration testing
  • Local blockchain simulation
  • Contract deployment testing
  • Gas usage optimization

Key Features:

  • JavaScript/TypeScript testing environment
  • Console.log debugging
  • Stack traces for errors
  • Network forking capabilities
  • Plugin ecosystem

Integration in Our Process: We use Hardhat for comprehensive test suites, particularly for complex DeFi protocols where interaction with mainnet contracts is required.

Foundry (Forge/Cast)

Description: Foundry is a blazing fast, portable and modular toolkit for Ethereum application development, with a focus on testing efficiency.

Use Cases:

  • High-performance smart contract testing
  • Fuzzing and property-based testing
  • Gas optimization
  • Mainnet forking and simulation

Key Features:

  • Written in Rust for high performance
  • Solidity-native testing
  • Advanced fuzzing capabilities
  • Cheatcodes for state manipulation
  • Extensive trace outputs

Integration in Our Process: We leverage Foundry for its performance advantages and powerful fuzzing capabilities, particularly for projects requiring extensive test permutations.

Specialized Testing Tools

Echidna

Description: Echidna is a property-based fuzzing tool designed specifically for Ethereum smart contracts.

Use Cases:

  • Finding edge cases through fuzzing
  • Property-based testing
  • Invariant testing
  • Discovering unexpected state transitions

Key Features:

  • Smart fuzzing based on coverage
  • Property testing in Solidity
  • Corpus generation and mutation
  • Detailed test case reporting

Integration in Our Process: We apply Echidna to discover edge cases and boundary conditions that might not be covered by standard test suites.

Tenderly

Description: Tenderly is a platform for monitoring, alerting, debugging, and simulating Ethereum smart contracts.

Use Cases:

  • Transaction simulation and debugging
  • Gas profiling
  • Contract verification
  • Real-time monitoring

Key Features:

  • Visual debugger
  • Gas profiler
  • Custom alerts and notifications
  • Transaction simulations

Integration in Our Process: We use Tenderly for simulating complex interactions and debugging transaction failures during the verification phase.

Testing Methodologies

Unit Testing

Our unit testing approach:

  • Tests each function in isolation
  • Verifies correct behavior for valid inputs
  • Checks proper handling of invalid inputs
  • Confirms expected events are emitted
  • Verifies state changes

Integration Testing

Our integration testing strategy:

  • Tests interactions between contract components
  • Verifies correct composite behavior
  • Checks multi-step workflows
  • Tests contract upgrades and migrations

Property-Based Testing

We employ property-based testing to:

  • Identify invariants that should always hold
  • Generate random inputs to test boundary conditions
  • Discover unexpected edge cases
  • Verify mathematical properties

Economic Testing

For DeFi protocols, we conduct economic testing to:

  • Simulate various market conditions
  • Test economic incentive alignment
  • Verify no adversarial profit opportunities exist
  • Check resistance to common economic attacks

Scenario Testing

We develop scenario tests to:

  • Simulate real-world usage patterns
  • Test complex interaction sequences
  • Verify behavior in extreme conditions
  • Check recovery from failure states

Testing Best Practices

Our testing process follows these best practices:

Coverage-Driven Testing

  • We aim for 100% code coverage where practical
  • Beyond line coverage, we focus on path and branch coverage
  • We identify and test critical paths extensively
  • Coverage reports guide additional test development

Gas Optimization Testing

  • We measure gas consumption in tests
  • We compare gas usage against baselines
  • We identify gas-intensive operations and optimization opportunities
  • We test gas usage under different network conditions

Mainnet Forking

  • We test against production state when relevant
  • We simulate interactions with existing protocols
  • We verify compatibility with deployed contracts
  • We check behavior with real-world data and state

Continuous Integration

  • We integrate testing into CI/CD pipelines
  • We enforce test passage before deployment
  • We track test metrics over time
  • We maintain regression test suites

Comprehensive testing is not merely a verification step but an integral part of the security development lifecycle. By combining multiple testing frameworks and methodologies, we can identify and address vulnerabilities that might otherwise reach production.