foundry icon indicating copy to clipboard operation
foundry copied to clipboard

SEVERE: --via-r in combination with vm.warp break solidity execution and overrides stack variables

Open RitzyDevUK opened this issue 9 months ago • 0 comments

Component

Forge

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

  • [X] Foundry
  • [X] Foundryup

What version of Foundry are you on?

forge 0.2.0 (503792a 2024-05-11T00:16:33.765886985Z)

What command(s) is the bug in?

forge test -vvv --via-r

Operating System

Linux

Describe the bug

I created a simple test to show the issue clearly:

event WarpTime(uint256 time);
function testWTF() public {

    uint256 waitStep = 10000;

    address user1 = vm.addr(1);
    uint256 count = 6;
    
    vm.startPrank(user1);
    uint256 timestamp = block.timestamp;
    for (uint256 i = 0; i < count; i++) {
        uint256 step = i+1;
        uint256 releaseTime = timestamp + (waitStep * step);
        emit WarpTime(releaseTime);
    }

    //Validate that the iterations are not causing the bug
    for (uint256 i = 0; i < count; i++) {
        uint256 step = i+1;
        uint256 releaseTime = timestamp + (waitStep * step);
        emit WarpTime(releaseTime);
    }

    // Validate that warp time breaks the --via-r compilations
    for (uint256 i = 0; i < count; i++) {
        uint256 step = i+1;
        uint256 releaseTime = timestamp + (waitStep * step);
        vm.warp(releaseTime);
        emit WarpTime(releaseTime);
    }

    //Intentionally fail to show the logs above
    assertTrue(false);

    vm.stopPrank();
}

Here are the logs from the test ran:

Traces: [37530] AssetManagerTest::testWTF() ├─ [0] VM::addr() [staticcall] │ └─ ← [Return] 0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf ├─ [0] VM::startPrank(0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf) │ └─ ← [Return] ├─ emit WarpTime(time: 10001 [1e4]) ├─ emit WarpTime(time: 20001 [2e4]) ├─ emit WarpTime(time: 30001 [3e4]) ├─ emit WarpTime(time: 40001 [4e4]) ├─ emit WarpTime(time: 50001 [5e4]) ├─ emit WarpTime(time: 60001 [6e4]) ├─ emit WarpTime(time: 10001 [1e4]) ├─ emit WarpTime(time: 20001 [2e4]) ├─ emit WarpTime(time: 30001 [3e4]) ├─ emit WarpTime(time: 40001 [4e4]) ├─ emit WarpTime(time: 50001 [5e4]) ├─ emit WarpTime(time: 60001 [6e4]) ├─ [0] VM::warp(10001 [1e4]) │ └─ ← [Return] ├─ emit WarpTime(time: 10001 [1e4]) ├─ [0] VM::warp(30001 [3e4]) │ └─ ← [Return] ├─ emit WarpTime(time: 30001 [3e4]) ├─ [0] VM::warp(60001 [6e4]) │ └─ ← [Return] ├─ emit WarpTime(time: 60001 [6e4]) ├─ [0] VM::warp(100001 [1e5]) │ └─ ← [Return] ├─ emit WarpTime(time: 100001 [1e5]) ├─ [0] VM::warp(150001 [1.5e5]) │ └─ ← [Return] ├─ emit WarpTime(time: 150001 [1.5e5]) ├─ [0] VM::warp(210001 [2.1e5]) │ └─ ← [Return] ├─ emit WarpTime(time: 210001 [2.1e5]) ├─ emit log(val: "Error: Assertion Failed") ├─ [0] VM::store(VM: [0x7109709ECfa91a80626fF3989D68f67F5b1DD12D], 0x6661696c65640000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000001) │ └─ ← [Return] ├─ [0] VM::stopPrank() │ └─ ← [Return] └─ ← [Return]

As you can see from execution:

  1. vm.warp when executing under --via-r is cumulatively adding the previous block time to the warp after the first warp vm.warp(10001) = 10001 // sets the warp block + 10000 vm.warp(20001) = 30001 // sets the warp block + 10000 + 20000
  2. vm.warp is overriding the internal stack variable for releaseTime, as the Event is emitting the same value as the warp time.

RitzyDevUK avatar May 12 '24 00:05 RitzyDevUK