# Fuzz

{% embed url="https://youtu.be/6sMOeuqwk-U" %}
Fuzz
{% endembed %}

## Setup

Target contract:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

contract Bit {
    // Find most significant bit using binary search
    function mostSignificantBit(uint256 x)
        external
        pure
        returns (uint256 msb)
    {
        // x >= 2 ** 128
        if (x >= 0x100000000000000000000000000000000) {
            x >>= 128;
            msb += 128;
        }
        // x >= 2 ** 64
        if (x >= 0x10000000000000000) {
            x >>= 64;
            msb += 64;
        }
        // x >= 2 ** 32
        if (x >= 0x100000000) {
            x >>= 32;
            msb += 32;
        }
        // x >= 2 ** 16
        if (x >= 0x10000) {
            x >>= 16;
            msb += 16;
        }
        // x >= 2 ** 8
        if (x >= 0x100) {
            x >>= 8;
            msb += 8;
        }
        // x >= 2 ** 4
        if (x >= 0x10) {
            x >>= 4;
            msb += 4;
        }
        // x >= 2 ** 2
        if (x >= 0x4) {
            x >>= 2;
            msb += 2;
        }
        // x >= 2 ** 1
        if (x >= 0x2) msb += 1;
    }
}
```

Test file:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

import "forge-std/Test.sol";
import {Bit} from "../src/Bit.sol";

// forge test --match-path test/Fuzz.t.sol

// Topics
// - fuzz
// - assume and bound
// - stats
//   (runs: 256, μ: 18301, ~: 10819)
//   runs - number of tests
//   μ - mean gas used
//   ~ - median gas used

contract FuzzTest is Test {
    Bit public b;

    function setUp() public {
        b = new Bit();
    }

    function mostSignificantBit(uint256 x) private pure returns (uint256) {
        uint256 i = 0;
        while ((x >>= 1) > 0) {
            i++;
        }
        return i;
    }

    function testMostSignificantBitManual() public {
        assertEq(b.mostSignificantBit(0), 0);
        assertEq(b.mostSignificantBit(1), 0);
        assertEq(b.mostSignificantBit(2), 1);
        assertEq(b.mostSignificantBit(4), 2);
        assertEq(b.mostSignificantBit(8), 3);
        assertEq(b.mostSignificantBit(type(uint256).max), 255);
    }

    function testMostSignificantBitFuzz(uint256 x) public {
        // assume - If false, the fuzzer will discard the current fuzz inputs
        //          and start a new fuzz run
        // Skip x = 0
        // vm.assume(x > 0);
        // assertGt(x, 0);

        // bound(input, min, max) - bound input between min and max
        // Bound
        x = bound(x, 1, 10);
        // assertGe(x, 1);
        // assertLe(x, 10);

        uint256 i = b.mostSignificantBit(x);
        assertEq(i, mostSignificantBit(x));
    }
}
```

## What is fuzzing?

{% embed url="https://book.getfoundry.sh/forge/fuzz-testing" %}

Fuzzing basically means generating a bunch of random inputs and feeding them into a function. If the input violates the assertion, then we just found a bug.

A usual test case in a Foundry test does not have input parameter. If there is input parameter, then Foundry will consider it as a fuzzing scenario. For example:

```solidity
contract SafeTest is Test {
    // ...

    function testFuzz_Withdraw(uint256 amount) public {
        payable(address(safe)).transfer(amount);
        uint256 preBalance = address(this).balance;
        safe.withdraw();
        uint256 postBalance = address(this).balance;
        assertEq(preBalance + amount, postBalance);
    }
}

```

## bound and assume

Back to the `Bit` contract. If we want to limit the value of `x` in a certain range, we can use `vm.assume()`.  This cheatcode is going to set a constrait on `x` generated by the fuzzer: if the generated input does not satisfy the condition, fuzzer is going to drop it and start another round of fuzzing. For example:

```solidity
vm.assume(x > 0);
```

If `x <= 0` then it will be dropped.

Another way of setting a range for `x` is using `bound()`. It sets lower bound and upper bound for `x`:

```solidity
x = bound(x, 1, 10);
```

In the end we would feed `x` into the function and test its result:

```solidity
uint256 i = b.mostSignificantBit(x);
assertEq(i, mostSignificantBit(x));
```

<figure><img src="https://3988450783-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVjG_njKgBtvmnKaJh%2Fuploads%2Fd8RiD57NkGoK5x8Yp4ib%2Fimage.png?alt=media&#x26;token=8c923641-3ec9-4311-a53d-7bc3e85d9559" alt=""><figcaption></figcaption></figure>
