You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a bug that I encountered when I was tracking the test coverage of a rather complicated solidity project.
However, here is a simple project to replicate the same bug:
And there are two contracts with the same name (UseLib) but defined in different files:
UseLib defined in file UseLib0.sol depends on LibA
UseLib defined in file UseLib1.sol depends on LibB
// UseLib0.sol // SPDX-License-Identifier: UNLICENSEDpragma solidity^0.8.13;
import"./LibA.sol";
contractUseLib {
mapping (uint=>uint) numbers;
function getValue() externalviewreturns(uint256){
// Note: The code of the two "UseLib" contracts must be different// If the difference score between them is too low,// the hits of the two contracts may be accidently merged into one: // https://github.com/foundry-rs/foundry/blob/8c4893233c7d54de3787227577cd0e3a4faa8945/common/src/contracts.rs#L25uint seed = LibA.getLibValue();
uint sum =0;
// do more stuffs to make the code more distinctive from the other for(uint i=0; i < seed; ++i){
sum += numbers[i];
}
return sum;
}
}
// SPDX-License-Identifier: UNLICENSEDpragma solidity^0.8.13;
import"forge-std/Test.sol";
import {UseLib as UseLibFrom0} from"../src/UseLib0.sol";
import {UseLib as UseLibFrom1} from"../src/UseLib1.sol";
contractTestAisTest {
UseLibFrom0 sut0;
UseLibFrom1 sut1;
function setUp() external{
sut0 =newUseLibFrom0();
sut1 =newUseLibFrom1();
}
function test_GetA() external {
uint256 result = sut0.getValue();
assertEq(result, 0);
result = sut1.getValue();
assertEq(result, 1);
}
}
Okay, Let's see the summary & debug coverage report:
| File | % Lines | % Statements | % Branches | % Funcs |
|-----------------|---------------|---------------|---------------|---------------|
| src/LibA.sol | 100.00% (1/1) | 100.00% (1/1) | 100.00% (0/0) | 100.00% (1/1) |
| src/LibB.sol | 100.00% (1/1) | 100.00% (1/1) | 100.00% (0/0) | 100.00% (1/1) |
| src/UseLib0.sol | 0.00% (0/5) | 0.00% (0/8) | 100.00% (0/0) | 0.00% (0/1) |
| src/UseLib1.sol | 100.00% (2/2) | 100.00% (3/3) | 100.00% (0/0) | 100.00% (1/1) |
| Total | 44.44% (4/9) | 38.46% (5/13) | 100.00% (0/0) | 75.00% (3/4) |
Uncovered for src/LibA.sol:
Uncovered for src/LibB.sol:
Uncovered for src/UseLib0.sol:
- Function "getValue" (location: source ID 19, line 11, chars 152-457, hits: 0)
- Line (location: source ID 19, line 12, chars 212-242, hits: 0)
- Statement (location: source ID 19, line 12, chars 212-242, hits: 0)
- Statement (location: source ID 19, line 12, chars 224-242, hits: 0)
- Line (location: source ID 19, line 14, chars 261-273, hits: 0)
- Statement (location: source ID 19, line 14, chars 261-273, hits: 0)
- Line (location: source ID 19, line 16, chars 364-372, hits: 0)
- Statement (location: source ID 19, line 16, chars 364-372, hits: 0)
- Statement (location: source ID 19, line 16, chars 374-382, hits: 0)
- Statement (location: source ID 19, line 16, chars 384-387, hits: 0)
- Line (location: source ID 19, line 17, chars 402-419, hits: 0)
- Statement (location: source ID 19, line 17, chars 402-419, hits: 0)
- Line (location: source ID 19, line 20, chars 440-450, hits: 0)
- Statement (location: source ID 19, line 20, chars 440-450, hits: 0)
Uncovered for src/UseLib1.sol:
Anchors for Contract "LibA" (solc 0.8.20+commit.a1b79de6.Darwin.appleclang, source ID 17):
- IC 58 -> Item 23
- Refers to item: Function "getLibValue" (location: source ID 17, line 7, chars 90-167, hits: 1)
- IC 91 -> Item 24
- Refers to item: Line (location: source ID 17, line 9, chars 156-159, hits: 1)
- IC 91 -> Item 25
- Refers to item: Statement (location: source ID 17, line 9, chars 156-159, hits: 1)
Anchors for Contract "LibB" (solc 0.8.20+commit.a1b79de6.Darwin.appleclang, source ID 18):
- IC 58 -> Item 20
- Refers to item: Function "getLibValue" (location: source ID 18, line 7, chars 90-166, hits: 1)
- IC 91 -> Item 21
- Refers to item: Line (location: source ID 18, line 9, chars 156-159, hits: 1)
- IC 91 -> Item 22
- Refers to item: Statement (location: source ID 18, line 9, chars 156-159, hits: 1)
Anchors for Contract "UseLib" (solc 0.8.20+commit.a1b79de6.Darwin.appleclang, source ID 20):
- IC 48 -> Item 14
- Refers to item: Function "getValue" (location: source ID 20, line 12, chars 129-245, hits: 1)
- IC 81 -> Item 15
- Refers to item: Line (location: source ID 20, line 13, chars 189-220, hits: 1)
- IC 81 -> Item 16
- Refers to item: Statement (location: source ID 20, line 13, chars 189-220, hits: 1)
- IC 82 -> Item 17
- Refers to item: Statement (location: source ID 20, line 13, chars 198-220, hits: 1)
- IC 206 -> Item 18
- Refers to item: Line (location: source ID 20, line 14, chars 230-238, hits: 1)
- IC 206 -> Item 19
- Refers to item: Statement (location: source ID 20, line 14, chars 230-238, hits: 1)
Anchors for Contract "UseLib" (solc 0.8.20+commit.a1b79de6.Darwin.appleclang, source ID 19):
- IC 48 -> Item 0
- Refers to item: Function "getValue" (location: source ID 19, line 11, chars 152-457, hits: 0)
- IC 81 -> Item 1
- Refers to item: Line (location: source ID 19, line 12, chars 212-242, hits: 0)
- IC 81 -> Item 2
- Refers to item: Statement (location: source ID 19, line 12, chars 212-242, hits: 0)
- IC 82 -> Item 3
- Refers to item: Statement (location: source ID 19, line 12, chars 224-242, hits: 0)
- IC 193 -> Item 4
- Refers to item: Line (location: source ID 19, line 14, chars 261-273, hits: 0)
- IC 193 -> Item 5
- Refers to item: Statement (location: source ID 19, line 14, chars 261-273, hits: 0)
- IC 195 -> Item 6
- Refers to item: Line (location: source ID 19, line 16, chars 364-372, hits: 0)
- IC 195 -> Item 7
- Refers to item: Statement (location: source ID 19, line 16, chars 364-372, hits: 0)
- IC 197 -> Item 8
- Refers to item: Statement (location: source ID 19, line 16, chars 374-382, hits: 0)
- IC 237 -> Item 9
- Refers to item: Statement (location: source ID 19, line 16, chars 384-387, hits: 0)
- IC 205 -> Item 10
- Refers to item: Line (location: source ID 19, line 17, chars 402-419, hits: 0)
- IC 205 -> Item 11
- Refers to item: Statement (location: source ID 19, line 17, chars 402-419, hits: 0)
- IC 255 -> Item 12
- Refers to item: Line (location: source ID 19, line 20, chars 440-450, hits: 0)
- IC 255 -> Item 13
- Refers to item: Statement (location: source ID 19, line 20, chars 440-450, hits: 0)
Note that hits of the UseLib contract from UseLib0.sol are missing.
And let's do some magics. If we change the name of the UseLib contract in UseLib0.sol to UseLibRenamed, the resulting coverage report correctly includes all the hits:
| File | % Lines | % Statements | % Branches | % Funcs |
|-----------------|---------------|-----------------|---------------|---------------|
| src/LibA.sol | 100.00% (1/1) | 100.00% (1/1) | 100.00% (0/0) | 100.00% (1/1) |
| src/LibB.sol | 100.00% (1/1) | 100.00% (1/1) | 100.00% (0/0) | 100.00% (1/1) |
| src/UseLib0.sol | 100.00% (5/5) | 100.00% (8/8) | 100.00% (0/0) | 100.00% (1/1) |
| src/UseLib1.sol | 100.00% (2/2) | 100.00% (3/3) | 100.00% (0/0) | 100.00% (1/1) |
| Total | 100.00% (9/9) | 100.00% (13/13) | 100.00% (0/0) | 100.00% (4/4) |
Uncovered for src/LibA.sol:
Uncovered for src/LibB.sol:
Uncovered for src/UseLib0.sol:
Uncovered for src/UseLib1.sol:
Anchors for Contract "UseLib" (solc 0.8.20+commit.a1b79de6.Darwin.appleclang, source ID 20):
- IC 48 -> Item 20
- Refers to item: Function "getValue" (location: source ID 20, line 12, chars 129-245, hits: 1)
- IC 81 -> Item 21
- Refers to item: Line (location: source ID 20, line 13, chars 189-220, hits: 1)
- IC 81 -> Item 22
- Refers to item: Statement (location: source ID 20, line 13, chars 189-220, hits: 1)
- IC 82 -> Item 23
- Refers to item: Statement (location: source ID 20, line 13, chars 198-220, hits: 1)
- IC 206 -> Item 24
- Refers to item: Line (location: source ID 20, line 14, chars 230-238, hits: 1)
- IC 206 -> Item 25
- Refers to item: Statement (location: source ID 20, line 14, chars 230-238, hits: 1)
Anchors for Contract "UseLibRenamed" (solc 0.8.20+commit.a1b79de6.Darwin.appleclang, source ID 19):
- IC 48 -> Item 0
- Refers to item: Function "getValue" (location: source ID 19, line 11, chars 159-799, hits: 1)
- IC 81 -> Item 1
- Refers to item: Line (location: source ID 19, line 18, chars 554-584, hits: 1)
- IC 81 -> Item 2
- Refers to item: Statement (location: source ID 19, line 18, chars 554-584, hits: 1)
- IC 82 -> Item 3
- Refers to item: Statement (location: source ID 19, line 18, chars 566-584, hits: 1)
- IC 193 -> Item 4
- Refers to item: Line (location: source ID 19, line 20, chars 603-615, hits: 1)
- IC 193 -> Item 5
- Refers to item: Statement (location: source ID 19, line 20, chars 603-615, hits: 1)
- IC 195 -> Item 6
- Refers to item: Line (location: source ID 19, line 22, chars 706-714, hits: 1)
- IC 195 -> Item 7
- Refers to item: Statement (location: source ID 19, line 22, chars 706-714, hits: 1)
- IC 197 -> Item 8
- Refers to item: Statement (location: source ID 19, line 22, chars 716-724, hits: 2)
- IC 237 -> Item 9
- Refers to item: Statement (location: source ID 19, line 22, chars 726-729, hits: 1)
- IC 205 -> Item 10
- Refers to item: Line (location: source ID 19, line 23, chars 744-761, hits: 1)
- IC 205 -> Item 11
- Refers to item: Statement (location: source ID 19, line 23, chars 744-761, hits: 1)
- IC 255 -> Item 12
- Refers to item: Line (location: source ID 19, line 26, chars 782-792, hits: 1)
- IC 255 -> Item 13
- Refers to item: Statement (location: source ID 19, line 26, chars 782-792, hits: 1)
Anchors for Contract "LibA" (solc 0.8.20+commit.a1b79de6.Darwin.appleclang, source ID 17):
- IC 58 -> Item 17
- Refers to item: Function "getLibValue" (location: source ID 17, line 7, chars 90-167, hits: 1)
- IC 91 -> Item 18
- Refers to item: Line (location: source ID 17, line 9, chars 156-159, hits: 1)
- IC 91 -> Item 19
- Refers to item: Statement (location: source ID 17, line 9, chars 156-159, hits: 1)
Anchors for Contract "LibB" (solc 0.8.20+commit.a1b79de6.Darwin.appleclang, source ID 18):
- IC 58 -> Item 14
- Refers to item: Function "getLibValue" (location: source ID 18, line 7, chars 90-166, hits: 1)
- IC 91 -> Item 15
- Refers to item: Line (location: source ID 18, line 9, chars 156-159, hits: 1)
- IC 91 -> Item 16
- Refers to item: Statement (location: source ID 18, line 9, chars 156-159, hits: 1)
Possible Cause ?
Two contracts with the same from different files will have the same slug.
Component
Forge
Have you ensured that all of these are up to date?
What version of Foundry are you on?
commit 8c48932
What command(s) is the bug in?
coverage
Operating System
macOS (Intel)
Describe the bug
Issue
This is a bug that I encountered when I was tracking the test coverage of a rather complicated solidity project.
However, here is a simple project to replicate the same bug:
There are two simple libraries:
LibA
andLibB
:LibA
from fileLibA.sol
LibB
from fileLibB.sol
And there are two contracts with the same name (
UseLib
) but defined in different files:UseLib
defined in fileUseLib0.sol
depends onLibA
UseLib
defined in fileUseLib1.sol
depends onLibB
And the test script is as follows:
Okay, Let's see the summary & debug coverage report:
Note that hits of the
UseLib
contract fromUseLib0.sol
are missing.And let's do some magics. If we change the name of the
UseLib
contract inUseLib0.sol
toUseLibRenamed
, the resulting coverage report correctly includes all the hits:Possible Cause ?
Two contracts with the same from different files will have the same
slug
.foundry/utils/src/lib.rs
Line 142 in 8c48932
The text was updated successfully, but these errors were encountered: