Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forge coverage for modifiers is missing/incomplete #3489

Closed
2 tasks done
ChiTimesChi opened this issue Oct 13, 2022 · 3 comments · Fixed by #7669
Closed
2 tasks done

Forge coverage for modifiers is missing/incomplete #3489

ChiTimesChi opened this issue Oct 13, 2022 · 3 comments · Fixed by #7669
Labels
C-forge Command: forge Cmd-forge-coverage Command: forge coverage T-bug Type: bug

Comments

@ChiTimesChi
Copy link

Component

Forge

Have you ensured that all of these are up to date?

  • Foundry
  • Foundryup

What version of Foundry are you on?

forge 0.2.0 (28312e7 2022-10-13T00:10:05.477412592Z)

What command(s) is the bug in?

forge coverage

Operating System

Linux

Describe the bug

Contract example

Contracts Bar and Foo are identical in terms of what they are doing, the difference is whether the security check is done in the function modifier or not.

Full example is available here: https://github.com/ChiTimesChi/coverage-modifier

abstract contract Ownable {
    address public owner;

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(owner == msg.sender, "!owner");
        _;
    }
}

contract Bar is Ownable {
    event BarEvent();

    function bar() external {
        require(owner == msg.sender, "!owner");
        emit BarEvent();
    }
}

contract Foo is Ownable {
    event FooEvent();

    function foo() external onlyOwner {
        emit FooEvent();
    }
}

Tests example

This set of tests doesn't include "try calling as not owner" tests.

contract FoobarTest is Test {
    event BarEvent();
    event FooEvent();

    Foo internal foo;
    Bar internal bar;

    function setUp() public {
        foo = new Foo();
        bar = new Bar();
    }

    function testFooAsOwner() public {
        vm.expectEmit(true, true, true, true);
        emit FooEvent();
        foo.foo();
    }

    function testBarAsOwner() public {
        vm.expectEmit(true, true, true, true);
        emit BarEvent();
        bar.bar();
    }
}

Coverage

image
image
image

As you can see, the coverage report hints that the Bar tests are incomplete, but for Foo there's no way to tell that. The coverage for Ownable is missing entirely (contract being non abstract doesn't change anything).

Expected coverage

What I was hoping to see? Ideally, if a function has a few modifiers, the coverage report should not differ too much from the very same function rewritten without any modifiers. Meaning that coverage should give me a clue as to whether the tests are covering not only all branches within the function, but within its modifiers as well.

sc-forks/solidity-coverage#286 is a good read as well.

@ChiTimesChi ChiTimesChi added the T-bug Type: bug label Oct 13, 2022
@rkrasiuk rkrasiuk added C-forge Command: forge Cmd-forge-coverage Command: forge coverage labels Oct 17, 2022
@ChiTimesChi
Copy link
Author

@rkrasiuk any update for this? I wasn't able to find any good solution to this, and ensuring that the tests cover all functions with "security" modifiers like onlyOwner is kind of crucial.

@rkrasiuk
Copy link
Collaborator

@onbjerg could you take a look pls?

@yorhodes
Copy link

yorhodes commented Jun 30, 2023

forge coverage basically unusable without this and other bug fixes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-forge Command: forge Cmd-forge-coverage Command: forge coverage T-bug Type: bug
Projects
Status: Completed
Development

Successfully merging a pull request may close this issue.

3 participants