Blockchain security isn't optional.
Protect your smart contracts and DeFi protocols with Three Sigma, a trusted security partner in blockchain audits, smart contract vulnerability assessments, and Web3 security.

Introduction
Foundry roll in hop is the pattern of fast-forwarding test state by rolling blocks with vm.roll
so you can “hop” through chain history. Paired with vm.warp
, you control timestamps for deadlines, vesting, auctions, and time-locks without waiting. In the previous article of the Foundry Series - Assertion Cheatcodes, we mastered negative testing and event verification. Today we get to play time-lord: vm.roll and vm.warp let your tests hop to any block number or timestamp, perfect for deadlines, vesting schedules, and block-based locks, especially when preparing for an economic audit of token vesting and emissions.
Cheatcode vm.roll
, Controlling the Block Number
In practice, foundry roll in hop lets you jump block numbers deterministically to test block-height logic. vm.roll(uint256 newHeight)
 jumps the blockchain’s block number to newHeight (keeping timestamp unchanged). This is useful for testing time-based or block-based logic. For example, many contracts lock functionality until a certain block or allow actions only when n blocks have passed. You can simulate that easily:

In the test, after deploying at N, you’d do:

Because Forge uses a deterministic EVM, the above call will indeed see block.number ≥ unlockBlock, allowing the action to succeed. Conversely, if you rolled to a lesser number, it would revert. If you’re reviewing access windows or delayed-execution patterns, our breakdown of smart contract vulnerabilities in upgradable contracts is a helpful companion read. Importantly, vm.roll only sets the block number, while the block timestamp (block.timestamp) remains what it was. Foundry also provides vm.warp to set the timestamp (see next section). In combination, you often advance both number and time to simulate progression, a common need when validating vesting cliffs and unlocks.
(A Foundry tutorial on a lottery contract, for instance, uses vm.warp(...)
and vm.roll(...)
back-to-back to simulate the passing of the lottery interval.)
Because block.number
is normally monotonic, vm.roll
can also be used to shrink (rewind) the block height by giving a smaller number, though care is needed since contracts may assume increasing blocks. This foundry roll in hop step ensures tests advance block height deterministically.
Advanced tip: Invariant or fuzz tests might internally use roll
to explore block-time invariants. Also, Forge’s block manipulation works seamlessly across forks, if you fork mainnet, vm.roll
still overrides the number for your test environment. Overall, vm.roll
unlocks any scenario where a certain block number condition must be met, without waiting in real-time.
Cheatcode vm.warp
, Controlling the Block Timestamp
Combine foundry roll in hop with vm.warp to align timestamps with your hopped blocks for end-to-end time logic. Similar to vm.roll, vm.warp(uint256 newTime)
 sets the blockchain’s current block.timestamp to newTime. This is essential for testing time-based logic (deadlines, vesting, interest accrual, etc.). For example, consider a time-lock:

In tests you might write:

The call to vm.warp(...)
leaps time to a point where block.timestamp >= releaseTime
, so the withdraw logic passes. If you tried calling before warp, it would revert as expected. Combining vm.warp
with vm.expectRevert
is a common pattern to test both pre- and post-deadline behavior.
Foundry also offers handy shortcuts: skip(x)
advances time by x
seconds, and rewind(x)
moves time backwards (if needed). But the core cheatcode is vm.warp
. As with roll, timestamp changes are only effective for the next transaction; the test context continues with the new time.
Remember: foundry roll in hop + vm.warp keeps block/time in sync for deadlines and unlocks.

In real contracts, you might need to test interest that accrues over time, auction expiration, or NFT reveal deadlines. vm.warp
lets you simulate long waits instantly. Just be mindful: if your contract also depends on block number, you may need both vm.warp
and vm.roll
together (or use skip
/rewind
which affect time only). In any case, these time-travel cheats make it trivial to hit very old or future timestamps.
Conclusion
Use foundry roll in hop to move block height with vm.roll, and control time with vm.warp
for realistic deadline and vesting tests. Keep block and timestamp changes paired, simulate edge cases, and document any assumptions in your test suite.
Frequently Asked Questions (FAQ)
What is “foundry roll in hop” and why use it?
“Foundry roll in hop” is a testing pattern where you advance block height with vm.roll to “hop” through chain history without waiting. It lets you simulate confirmations, epochs, or block-based logic deterministically in unit and integration tests.
When should I use vm.roll
vs vm.warp
?
Use vm.roll
to change block.number (block-height based logic: emissions per block, auction rounds, checkpointing). Use vm.warp
to change block.timestamp (time-based logic: deadlines, vesting cliffs, timelocks). Many scenarios need both: roll the block, then warp the timestamp to keep height and time aligned.
How do I avoid flaky tests when combining foundry roll in hop with vm.warp
?
Pair changes consistently: call vm.roll(n)
then vm.warp(t)
so both increase monotonically; respect protocol rules that enforce timestamp >= lastTimestamp + MIN_DELAY; re-read state after each hop; and document assumptions (e.g., expected slippage windows) so future test runs remain deterministic.