Properties vs Fuzz tests
1 min read

Properties vs Fuzz tests

Properties vs Fuzz tests
Photo by Piret Ilver / Unsplash

There are quite a few fuzzing related tools.

However, it's not always clear how they fit together in the fuzzing picture. Do you write properties with Scribble, or do you fuzz using foundry? An option that you should consider for your next fuzz test is using both!

Here is an example of a property and a fuzz test and how they are great together:

Property

A property is a statement that should be true.

For example, a token's total supply equals the sum of all its balances. Whether you're calling transfer(), approve() or balanceOf(), the property should always hold!

/// #invariant unchecked_sum(_balances) == _totalSupply;

Properties describe what a fuzzer should check in any scenario.

Fuzz Test

Fuzz tests describe a specific scenario with checks.

For example, you might write a fuzz test that performs two token transfers, one after the other. This fuzz test would likely check that the total amount transferred is equal to the sum of the two transfers.

function testDoubleTransfer(uint amount0, uint amount1) public {
    token.transfer(recipient, amount0);
    token.transfer(recipient, amount1);

    assertEq(token.balanceOf(recipient), amount0 + amount1);
}

👆 This is how that would look.

Properties ❤️ Fuzz Tests

So which one is better?

The truth is that properties don't compete with fuzz tests. They complement them well because fuzz tests can use the properties as (additional) checks!

For example, the fuzz test above wouldn't just check that the recipient receives the correct amount of tokens. It would also check that the balances are in check with the total supply.

Leverage Scribble's expressiveness and give properties a try for your next echidna, hypothesis, dapptools or foundry fuzz test!