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

feat(forge): native support for simulating the passage of time when running invariants #4994

Closed
PaulRBerg opened this issue May 21, 2023 · 5 comments · Fixed by #7819
Closed
Labels
A-testing Area: testing C-forge Command: forge Cmd-forge-test Command: forge test T-feature Type: feature

Comments

@PaulRBerg
Copy link
Contributor

PaulRBerg commented May 21, 2023

Component

Forge

Describe the feature you would like

Because most smart contract systems expect time to pass, it is a common need to simulate the passage of time (with vm.warp) when running invariant test campaigns with Foundry.

But this is difficult to do today because state is not preserved during invariants runs. Just look at Maple Finance's solution - they have to apply the useCurrentTimestamp modifier to all invariant tests, as well as all functions in the handler contracts.

Now, regardless of the state-preserving limitation and if and when it will be lifted, I posit that it would be helpful to offer native support for time warps in invariants.

Here's what I have in mind :

[profile.default.invariant]
  time_jump_min = 50
  time_jump_max = 1000

Nevermind the names - we can think about what would fit best later. What matters is the idea - to introduce two new config options which would be used for bounding a time jump that gets applied after every invariant test run, i.e. have Foundry do something like this:

modifier jump() {
    uint256 timeWarp = block.timestamp;
    timeWarp = _bound(timeWarp, 50 seconds, 1000 seconds);
    timestampStore.increaseCurrentTimestamp(timeWarp);
    vm.warp(timestampStore.currentTimestamp());
    _;
}

This way, an invariant test campaign would more accurately simulate the real world, where time passes between function calls.

Additional context

Related discussions:

@PaulRBerg PaulRBerg added the T-feature Type: feature label May 21, 2023
@gakonst gakonst added this to Foundry May 21, 2023
@github-project-automation github-project-automation bot moved this to Todo in Foundry May 21, 2023
@PaulRBerg PaulRBerg changed the title feat(forge): native support for simulate the passage of time when running invariants feat(forge): native support for simulating the passage of time when running invariants May 21, 2023
@simplyoptimistic
Copy link

I would also like something like this, but I would add that I think it makes sense to move forward blocks by some amount as well (e.g. perhaps by allowing the user to set the average frequency a new block is expected, to allow for variations across chains).

@mds1 mds1 added A-testing Area: testing C-forge Command: forge Cmd-forge-test Command: forge test labels Jun 25, 2023
@mds1
Copy link
Collaborator

mds1 commented Jun 25, 2023

I like the idea here. I'd suggest also adding a time_jump_frequency config value which is [0,100] which specifies the probability that you add a time jump before (and/or after?) the next function call to have a little more control. Since testing txs in the same block is also useful, and it'd be nice to have both scenarios with a single config.

Like @simplyoptimistic I think we should couple this with block number increases to keep those in sync to make sure things are realistic and minimize footguns.

Partly related to #749 (comment) where we discuss the idea of codegen'ing handler contracts that have properties like this defined

@viraj124
Copy link

viraj124 commented Jul 3, 2023

hey guys,
just wondering if there's an eta as to when this will be addressed as my invariant tests too have some dependency on block.timestamp but right it get's reset to the default value after 2-3 runs

@PaulRBerg
Copy link
Contributor Author

@viraj124 not sure about any ETA but in the meantime you can look at how we tackled this issue in our project sablier-labs/v2-core:

https://github.com/sablier-labs/v2-core/blob/f25aad3a3bff37b7b095aa77bfdc8a91add09382/test/invariant/stores/TimestampStore.sol

@viraj124
Copy link

viraj124 commented Jul 3, 2023

Thanks a lot @PaulRBerg this looks a elegant workaround was working on enabling something like this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-testing Area: testing C-forge Command: forge Cmd-forge-test Command: forge test T-feature Type: feature
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

4 participants