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
In my Foundry tests, I've discovered a peculiar issue concerning the handling of block.number. Normally, block.number should be dynamic, changing as the blockchain progresses, and this is indeed the case in tests when using vm.roll to simulate block progression. However, when block.number is assigned to a variable (like uint256 block1 = block.number;), unexpected behavior arises due to compiler optimizations. Instead of the variable retaining the block number at the time of assignment, it gets updated when vm.roll is used to change the block number. This is not in line with the expected behavior of Solidity in a live Ethereum environment, where a variable assigned with block.number should remain constant, reflecting the block number at the moment of assignment. This optimization-induced behavior can lead to misleading tests.
Was only able to reproduce this issue with via-ir enabled!
Expected Behavior:
The test should fail because block1 is expected to hold the value of block.number at the time of its assignment. When vm.roll(2) is called, block.number should change, but block1 should retain its original value.
Actual Behavior:
The test passes, indicating that block1 and block.number are treated as the same variable, likely due to compiler optimizations inlining block.number. This is inconsistent with how Solidity behaves in a live blockchain environment.
Impact:
This nuanced issue in Foundry tests, though uncommon, is noteworthy as it can cause unexpected outcomes, especially when comparing specific block numbers in detailed test scenarios.
Suggested Solutions/Improvements:
Considering that the issue seems to be confined to the test execution environment in Foundry, one possible solution could be the introduction of a cheat code. This cheat code could be designed to fetch the actual block.number value without being affected by the optimization or inlining process.
Request for Community Input:
I would appreciate any insights from other users or maintainers who might have encountered similar issues. Suggestions for temporary workarounds are also welcome until a more permanent solution is implemented. My workaround involved ceasing to record previous block numbers by directly fetching block.number. Instead, I assigned the same value of the expected block number values in the test passed in vm.roll.
The text was updated successfully, but these errors were encountered:
Component
Forge
Have you ensured that all of these are up to date?
What version of Foundry are you on?
forge 0.2.0 (67ab870 2023-12-27T00:16:03.636506444Z)
What command(s) is the bug in?
forge test
Operating System
Linux
Describe the bug
Description:
In my Foundry tests, I've discovered a peculiar issue concerning the handling of
block.number
. Normally,block.number
should be dynamic, changing as the blockchain progresses, and this is indeed the case in tests when usingvm.roll
to simulate block progression. However, whenblock.number
is assigned to a variable (likeuint256 block1 = block.number;
), unexpected behavior arises due to compiler optimizations. Instead of the variable retaining the block number at the time of assignment, it gets updated whenvm.roll
is used to change the block number. This is not in line with the expected behavior of Solidity in a live Ethereum environment, where a variable assigned withblock.number
should remain constant, reflecting the block number at the moment of assignment. This optimization-induced behavior can lead to misleading tests.Was only able to reproduce this issue with
via-ir
enabled!Code Snippet to Reproduce:
Here is a passing test run that should fail (CI only fails due to failing to create coverage report): https://github.com/0xLightt/inlined-block-number/actions/runs/7342836645/job/19992591620
Expected Behavior:
The test should fail because
block1
is expected to hold the value ofblock.number
at the time of its assignment. Whenvm.roll(2)
is called,block.number
should change, butblock1
should retain its original value.Actual Behavior:
The test passes, indicating that
block1
andblock.number
are treated as the same variable, likely due to compiler optimizations inliningblock.number
. This is inconsistent with how Solidity behaves in a live blockchain environment.Impact:
This nuanced issue in Foundry tests, though uncommon, is noteworthy as it can cause unexpected outcomes, especially when comparing specific block numbers in detailed test scenarios.
Suggested Solutions/Improvements:
Considering that the issue seems to be confined to the test execution environment in Foundry, one possible solution could be the introduction of a cheat code. This cheat code could be designed to fetch the actual block.number value without being affected by the optimization or inlining process.
Request for Community Input:
I would appreciate any insights from other users or maintainers who might have encountered similar issues. Suggestions for temporary workarounds are also welcome until a more permanent solution is implemented. My workaround involved ceasing to record previous block numbers by directly fetching block.number. Instead, I assigned the same value of the expected block number values in the test passed in
vm.roll
.The text was updated successfully, but these errors were encountered: