Skip to content

Commit

Permalink
feat(cheatcodes): getBlockNumber and getBlockTimestamp (#6630)
Browse files Browse the repository at this point in the history
* feat: getBlockTimestamp and getBlockHeight

* tests

* chore: rename getBlockHeight to getBlockNumber

* cargo cheats

* chore: make fns safe & view

* Update testdata/cheats/GetBlockTimestamp.t.sol

Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com>

* chore: update docs

* chore: cargo cheats

---------

Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com>
  • Loading branch information
Evalir and DaniPopes committed Dec 21, 2023
1 parent df49ddd commit cb6c44d
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 0 deletions.
40 changes: 40 additions & 0 deletions crates/cheatcodes/assets/cheatcodes.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions crates/cheatcodes/spec/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,13 @@ interface Vm {
#[cheatcode(group = Evm, safety = Unsafe)]
function roll(uint256 newHeight) external;

/// Gets the current `block.number`.
/// You should use this instead of `block.number` if you use `vm.roll`, as `block.number` is assumed to be constant across a transaction,
/// and as a result will get optimized out by the compiler.
/// See https://github.com/foundry-rs/foundry/issues/6180
#[cheatcode(group = Evm, safety = Safe)]
function getBlockNumber() external view returns (uint256 height);

/// Sets `tx.gasprice`.
#[cheatcode(group = Evm, safety = Unsafe)]
function txGasPrice(uint256 newGasPrice) external;
Expand All @@ -325,6 +332,13 @@ interface Vm {
#[cheatcode(group = Evm, safety = Unsafe)]
function warp(uint256 newTimestamp) external;

/// Gets the current `block.timestamp`.
/// You should use this instead of `block.timestamp` if you use `vm.warp`, as `block.timestamp` is assumed to be constant across a transaction,
/// and as a result will get optimized out by the compiler.
/// See https://github.com/foundry-rs/foundry/issues/6180
#[cheatcode(group = Evm, safety = Safe)]
function getBlockTimestamp() external view returns (uint256 timestamp);

// -------- Account State --------

/// Sets an address' balance.
Expand Down
14 changes: 14 additions & 0 deletions crates/cheatcodes/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,13 @@ impl Cheatcode for rollCall {
}
}

impl Cheatcode for getBlockNumberCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self {} = self;
Ok(ccx.data.env.block.number.abi_encode())
}
}

impl Cheatcode for txGasPriceCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { newGasPrice } = self;
Expand All @@ -226,6 +233,13 @@ impl Cheatcode for warpCall {
}
}

impl Cheatcode for getBlockTimestampCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self {} = self;
Ok(ccx.data.env.block.timestamp.abi_encode())
}
}

impl Cheatcode for dealCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self { account: address, newBalance: new_balance } = *self;
Expand Down
26 changes: 26 additions & 0 deletions testdata/cheats/GetBlockTimestamp.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity 0.8.18;

import "ds-test/test.sol";
import "./Vm.sol";

contract GetBlockTimestampTest is DSTest {
Vm constant vm = Vm(HEVM_ADDRESS);

function testGetTimestamp() public {
uint256 timestamp = vm.getBlockTimestamp();
assertEq(timestamp, 1, "timestamp should be 1");
}

function testGetTimestampWithWarp() public {
assertEq(vm.getBlockTimestamp(), 1, "timestamp should be 1");
vm.warp(10);
assertEq(vm.getBlockTimestamp(), 10, "warp failed");
}

function testGetTimestampWithWarpFuzzed(uint128 jump) public {
uint256 pre = vm.getBlockTimestamp();
vm.warp(pre + jump);
assertEq(vm.getBlockTimestamp(), pre + jump, "warp failed");
}
}
2 changes: 2 additions & 0 deletions testdata/cheats/Vm.sol

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions testdata/cheats/getBlockNumber.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity 0.8.18;

import "ds-test/test.sol";
import "./Vm.sol";

contract GetBlockNumberTest is DSTest {
Vm constant vm = Vm(HEVM_ADDRESS);

function testGetBlockNumber() public {
uint256 height = vm.getBlockNumber();
assertEq(height, uint256(block.number), "height should be equal to block.number");
}

function testGetBlockNumberWithRoll() public {
vm.roll(10);
assertEq(vm.getBlockNumber(), 10, "could not get correct block height after roll");
}

function testGetBlockNumberWithRollFuzzed(uint128 jump) public {
uint256 pre = vm.getBlockNumber();
vm.roll(pre + jump);
assertEq(vm.getBlockNumber(), pre + jump, "could not get correct block height after roll");
}
}

0 comments on commit cb6c44d

Please sign in to comment.