Introduction

On this page we will cover some of the more advanced testing techniques for assertions. All testing tools available in Forge are also available in Credible Layer testing, making it powerful and easy to write comprehensive tests for assertions.

Fuzz Testing

Fuzz testing is a technique to test general robustness of code as it runs many tests with random input. This is useful for assertions as it helps identify edge cases and unexpected behavior. You can use Forge’s built-in fuzz testing capabilities to test your assertions with random inputs.
function testAssertionAllowsValidWithdrawalFuzz(uint256 withdrawalAmount) public {
    // Bound the withdrawal amount to reasonable values
    vm.assume(withdrawalAmount > 0);
    vm.assume(withdrawalAmount <= assertionAdopter.deposits(user1));
    vm.assume(withdrawalAmount <= 100 ether); // Reasonable upper bound

    assertEq(assertionAdopter.deposits(user1), 5 ether);
    // Setup assertion for next transaction
    cl.assertion({
        adopter: address(assertionAdopter),
        createData: type(PhyLockAssertion).creationCode,
        fnSelector: PhyLockAssertion.assertionWithdrawInvariant.selector
    });

    // Execute withdrawal - this should succeed
    vm.prank(user1);
    assertionAdopter.withdraw(withdrawalAmount);

    assertEq(assertionAdopter.deposits(user1), 5 ether - withdrawalAmount);
}
This would run the test with 256 different values for withdrawalAmount that adhere to the bounds set by the vm.assume() constraints.
Use vm.assume() to filter out invalid inputs that would cause the test to fail for reasons unrelated to your assertion logic.

CI/CD Integration

You can set up CI/CD workflows to ensure all assertion tests pass before merging code. The setup is very similar to standard Foundry/Forge workflows, with the addition of installing pcl and running pcl test for testing.
name: Phylax Assertion Tests

on:
  pull_request:
    branches: [main, develop]
    paths:
      - "assertions/**"
      - "src/**"
  workflow_dispatch:

env:
  FOUNDRY_PROFILE: assertions

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          submodules: recursive

      - name: Setup Foundry
        uses: foundry-rs/foundry-toolchain@v1
        with:
          version: nightly

      - name: Install PCL CLI
        run: |
          LATEST_VERSION=$(curl -s https://api.github.com/repos/phylaxsystems/credible-sdk/releases/latest | grep '"tag_name":' | cut -d'"' -f4)
          curl -L "https://github.com/phylaxsystems/credible-sdk/releases/download/${LATEST_VERSION}/pcl-${LATEST_VERSION}-linux-x86_64.tar.gz" | tar -xz
          sudo mv pcl/pcl /usr/local/bin/
          sudo chmod +x /usr/local/bin/pcl

      - name: Run tests
        run: |
          pcl test
This workflow:
  • Triggers on pull requests to main/develop branches when assertion or source files change
  • Supports manual runs with workflow_dispatch
  • Uses the assertions profile via FOUNDRY_PROFILE: assertions
  • Installs the latest PCL CLI from GitHub releases
  • Runs all assertion tests with pcl test
Use the FOUNDRY_PROFILE: assertions environment variable to ensure the correct Foundry profile is used for testing assertions.

Foundry Profile Configuration

Foundry profiles allow you to configure different compilation and testing settings for different parts of your project. For assertions, you typically want a separate profile that focuses on the assertion-specific source code. This configuration goes in your project’s foundry.toml file, which you should be familiar with if you have used Foundry before.
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc_version = "0.8.29"
optimizer = true
optimizer_runs = 200

[profile.assertions]
src = "assertions/src"
out = "assertions/out"
libs = ["lib"]
solc_version = "0.8.29"
optimizer = true
optimizer_runs = 200
The assertions profile:
  • Separate source directory (assertions/src) - Keeps assertion code isolated
  • Separate output directory (assertions/out) - Prevents conflicts with main project artifacts
  • Same compiler settings - Ensures consistency with main project
When using pcl test or setting FOUNDRY_PROFILE=assertions, Foundry uses this profile configuration instead of the default one. You can set the FOUNDRY_PROFILE environment variable to assertions in your CI/CD workflow. Or can specify the profile to use when running tests like this:
FOUNDRY_PROFILE=assertions pcl test
If nothing is specified, the default profile is used.