From 32b71c37d708d9a884c1d5d76bb32c571be35ab2 Mon Sep 17 00:00:00 2001 From: gnkz Date: Thu, 17 Aug 2023 16:52:16 -0400 Subject: [PATCH 1/7] feat: add missing forge-std functions --- src/_modules/Accounts.sol | 9 ++++++++ src/_modules/Context.sol | 46 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/_modules/Accounts.sol b/src/_modules/Accounts.sol index 1951a2a5..27cfbe09 100644 --- a/src/_modules/Accounts.sol +++ b/src/_modules/Accounts.sol @@ -186,6 +186,15 @@ library accounts { return self; } + /// @dev Sets the nonce of the given `self` address to the arbitrary provided value `n`. + /// @param self The address to set the nonce for. + /// @param n The value to set the nonce to. + /// @return The updated address with the modified nonce. + function setArbitraryNonce(address self, uint64 n) internal returns (address) { + vulcan.hevm.setNonceUnsafe(self, n); + return self; + } + /// @dev Sets the `msg.sender` of the next call to `self`. /// @param self The address to impersonate. /// @return The address that was impersonated. diff --git a/src/_modules/Context.sol b/src/_modules/Context.sol index cda6349f..4a1ff38a 100644 --- a/src/_modules/Context.sol +++ b/src/_modules/Context.sol @@ -165,6 +165,13 @@ library ctx { return setBlockBaseFee(Context.wrap(0), baseFee); } + /// @dev Sets block.prevrandao. + /// @param newPrevrandao The new `block.prevrandao`. + function setBlockPrevrandao(Context self, bytes32 newPrevrandao) internal returns (Context) { + vulcan.hevm.prevrandao(newPrevrandao); + return self; + } + /// @dev sets the `block.chainid` to `chainId` /// @param chainId the new block chain id function setChainId(Context self, uint64 chainId) internal returns (Context) { @@ -194,6 +201,13 @@ library ctx { return setBlockCoinbase(Context.wrap(0), who); } + /// @dev Sets the transaction gas price. + /// @param newGasPrice The new transaction gas price. + function setGasPrice(Context self, uint256 newGasPrice) internal returns (Context) { + vulcan.hevm.txGasPrice(newGasPrice); + return self; + } + /// @dev Function used to check whether the next call reverts or not. /// @param revertData The function call data that that is expected to fail. function expectRevert(bytes memory revertData) internal { @@ -269,6 +283,23 @@ library ctx { vulcan.hevm.expectCall(callee, msgValue, data); } + + function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) internal { + vulcan.hevm.expectCallMinGas(callee, msgValue, minGas, data); + } + + function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data, uint64 count) external { + vulcan.hevm.expectCallMinGas(callee, msgValue, minGas, data, count); + } + + function expectSafeMemory(uint64 min, uint64 max) external { + vulcan.hevm.expectSafeMemory(min, max); + } + + function expectSafeMemoryCall(uint64 min, uint64 max) external { + vulcan.hevm.expectSafeMemoryCall(min, max); + } + /// @dev Takes a snapshot of the current state of the vm and returns an identifier. /// @return The snapshot identifier. function snapshot(Context) internal returns (uint256) { @@ -294,6 +325,21 @@ library ctx { function revertToSnapshot(uint256 snapshotId) internal returns (bool) { return revertToSnapshot(Context.wrap(0), snapshotId); } + + /// @dev Creates a breakpoint to jump to in the debugger. + /// @param name The name of the breakpoint. + function addBreakpoint(Context self, string memory name) internal returns (Context) { + vulcan.hevm.breakpoint(name); + return self; + } + + /// @dev Creates a breakpoint to jump to in the debugger. + /// @param name The name of the breakpoint. + /// @param condition The condition that needs to be fulfilled in order to add the breakpoint. + function addConditionalBreakpoint(Context self, string memory name, bool condition) internal returns (Context) { + vulcan.hevm.breakpoint(name, condition); + return self; + } } using ctx for Context global; From 6c1e9865f55d0fb8c12df5cfc52fe197faacf609 Mon Sep 17 00:00:00 2001 From: gnkz Date: Thu, 17 Aug 2023 16:54:19 -0400 Subject: [PATCH 2/7] style: fmt --- src/_modules/Context.sol | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/_modules/Context.sol b/src/_modules/Context.sol index 4a1ff38a..b61fd3a5 100644 --- a/src/_modules/Context.sol +++ b/src/_modules/Context.sol @@ -283,12 +283,13 @@ library ctx { vulcan.hevm.expectCall(callee, msgValue, data); } - function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) internal { vulcan.hevm.expectCallMinGas(callee, msgValue, minGas, data); } - function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data, uint64 count) external { + function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data, uint64 count) + external + { vulcan.hevm.expectCallMinGas(callee, msgValue, minGas, data, count); } From 9c028c29d7a2d0ac5e7dac0c6c0dcd81379fdbf2 Mon Sep 17 00:00:00 2001 From: gnkz Date: Fri, 18 Aug 2023 14:41:33 -0400 Subject: [PATCH 3/7] docs: add natspect for the new methods --- src/_modules/Accounts.sol | 5 +++-- src/_modules/Context.sol | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/_modules/Accounts.sol b/src/_modules/Accounts.sol index 27cfbe09..ac6aa368 100644 --- a/src/_modules/Accounts.sol +++ b/src/_modules/Accounts.sol @@ -177,7 +177,8 @@ library accounts { return self; } - /// @dev Sets the nonce of the given `self` address to the provided value `n`. + /// @dev Sets the nonce of the given `self` address to the provided value `n`. It will revert if + // the new nonce is lower than the current address nonce. /// @param self The address to set the nonce for. /// @param n The value to set the nonce to. /// @return The updated address with the modified nonce. @@ -190,7 +191,7 @@ library accounts { /// @param self The address to set the nonce for. /// @param n The value to set the nonce to. /// @return The updated address with the modified nonce. - function setArbitraryNonce(address self, uint64 n) internal returns (address) { + function setNonceUnsafe(address self, uint64 n) internal returns (address) { vulcan.hevm.setNonceUnsafe(self, n); return self; } diff --git a/src/_modules/Context.sol b/src/_modules/Context.sol index b61fd3a5..8ff77bdd 100644 --- a/src/_modules/Context.sol +++ b/src/_modules/Context.sol @@ -283,20 +283,39 @@ library ctx { vulcan.hevm.expectCall(callee, msgValue, data); } + /// @dev Expect a call to an address with the specified msg.value and calldata, and a minimum amount of gas. + /// @param callee The address that is expected to be called. + /// @param msgValue The `msg.value` that is expected to be sent. + /// @param minGas The expected minimum amount of gas for the call. + /// @param data The call data that is expected to be used. function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) internal { vulcan.hevm.expectCallMinGas(callee, msgValue, minGas, data); } + /// @dev Expect a call to an address with the specified msg.value and calldata, and a minimum amount of gas. + /// @param callee The address that is expected to be called. + /// @param msgValue The `msg.value` that is expected to be sent. + /// @param minGas The expected minimum amount of gas for the call. + /// @param data The call data that is expected to be used. + /// @param count The number of calls that are expected. function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data, uint64 count) external { vulcan.hevm.expectCallMinGas(callee, msgValue, minGas, data, count); } + /// @dev Allows to write on memory only between [0x00, 0x60) and [min, max) in the current + /// subcontext. + /// @param min The lower limit of the allowed memory slot. + /// @param max The upper limit of the allowed memory slot. function expectSafeMemory(uint64 min, uint64 max) external { vulcan.hevm.expectSafeMemory(min, max); } + /// @dev Allows to write on memory only between [0x00, 0x60) and [min, max) in the next + // subcontext. + /// @param min The lower limit of the allowed memory slot. + /// @param max The upper limit of the allowed memory slot. function expectSafeMemoryCall(uint64 min, uint64 max) external { vulcan.hevm.expectSafeMemoryCall(min, max); } From 522b1fa7d13e6ac7ee0f9d13ad60dfd89a1c001e Mon Sep 17 00:00:00 2001 From: gnkz Date: Fri, 18 Aug 2023 14:57:30 -0400 Subject: [PATCH 4/7] feat: adds the `setPrevrandao` method without context --- src/_modules/Context.sol | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/_modules/Context.sol b/src/_modules/Context.sol index 8ff77bdd..446f3a8a 100644 --- a/src/_modules/Context.sol +++ b/src/_modules/Context.sol @@ -172,6 +172,12 @@ library ctx { return self; } + /// @dev Sets block.prevrandao. + /// @param newPrevrandao The new `block.prevrandao`. + function setBlockPrevrandao(bytes32 newPrevrandao) internal returns (Context) { + return setBlockPrevrandao(Context.wrap(0), newPrevrandao); + } + /// @dev sets the `block.chainid` to `chainId` /// @param chainId the new block chain id function setChainId(Context self, uint64 chainId) internal returns (Context) { From a9f419390c95e0d42ef1dc106fbb2952fd06f02a Mon Sep 17 00:00:00 2001 From: gnkz Date: Fri, 18 Aug 2023 14:59:57 -0400 Subject: [PATCH 5/7] feat: adds the `setGrasPrice` method without Context --- src/_modules/Context.sol | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/_modules/Context.sol b/src/_modules/Context.sol index 446f3a8a..8d149ee0 100644 --- a/src/_modules/Context.sol +++ b/src/_modules/Context.sol @@ -214,6 +214,12 @@ library ctx { return self; } + /// @dev Sets the transaction gas price. + /// @param newGasPrice The new transaction gas price. + function setGasPrice(uint256 newGasPrice) internal returns (Context) { + return setGasPrice(Context.wrap(0), newGasPrice); + } + /// @dev Function used to check whether the next call reverts or not. /// @param revertData The function call data that that is expected to fail. function expectRevert(bytes memory revertData) internal { From 0900adc7de2c7925a17a8f5d6ca432f51d72e43e Mon Sep 17 00:00:00 2001 From: gnkz Date: Fri, 18 Aug 2023 15:15:02 -0400 Subject: [PATCH 6/7] docs: fix natspec --- src/_modules/Context.sol | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/_modules/Context.sol b/src/_modules/Context.sol index 8d149ee0..00029eae 100644 --- a/src/_modules/Context.sol +++ b/src/_modules/Context.sol @@ -304,7 +304,7 @@ library ctx { vulcan.hevm.expectCallMinGas(callee, msgValue, minGas, data); } - /// @dev Expect a call to an address with the specified msg.value and calldata, and a minimum amount of gas. + /// @dev Expect a number call to an address with the specified msg.value and calldata, and a minimum amount of gas. /// @param callee The address that is expected to be called. /// @param msgValue The `msg.value` that is expected to be sent. /// @param minGas The expected minimum amount of gas for the call. @@ -316,7 +316,7 @@ library ctx { vulcan.hevm.expectCallMinGas(callee, msgValue, minGas, data, count); } - /// @dev Allows to write on memory only between [0x00, 0x60) and [min, max) in the current + /// @dev Allows to write on memory only between [0x00, 0x60) and [min, max) in the current. /// subcontext. /// @param min The lower limit of the allowed memory slot. /// @param max The upper limit of the allowed memory slot. @@ -328,7 +328,7 @@ library ctx { // subcontext. /// @param min The lower limit of the allowed memory slot. /// @param max The upper limit of the allowed memory slot. - function expectSafeMemoryCall(uint64 min, uint64 max) external { + function expectsafememorycall(uint64 min, uint64 max) external { vulcan.hevm.expectSafeMemoryCall(min, max); } @@ -365,6 +365,12 @@ library ctx { return self; } + /// @dev Creates a breakpoint to jump to in the debugger. + /// @param name The name of the breakpoint. + function addBreakpoint(string memory name) internal returns (Context) { + return addBreakpoint(Context.wrap(0), name); + } + /// @dev Creates a breakpoint to jump to in the debugger. /// @param name The name of the breakpoint. /// @param condition The condition that needs to be fulfilled in order to add the breakpoint. @@ -372,6 +378,13 @@ library ctx { vulcan.hevm.breakpoint(name, condition); return self; } + + /// @dev Creates a breakpoint to jump to in the debugger. + /// @param name The name of the breakpoint. + /// @param condition The condition that needs to be fulfilled in order to add the breakpoint. + function addConditionalBreakpoint(string memory name, bool condition) internal returns (Context) { + return addConditionalBreakpoint(Context.wrap(0), name, condition); + } } using ctx for Context global; From bf61bf5ad575910210fe938569b18341f33c1541 Mon Sep 17 00:00:00 2001 From: gnkz Date: Fri, 18 Aug 2023 15:15:19 -0400 Subject: [PATCH 7/7] docs: add book docs --- docs/src/reference/modules/accounts.md | 7 +++- docs/src/reference/modules/context.md | 48 ++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/docs/src/reference/modules/accounts.md b/docs/src/reference/modules/accounts.md index e08dddee..849c6cca 100644 --- a/docs/src/reference/modules/accounts.md +++ b/docs/src/reference/modules/accounts.md @@ -54,7 +54,12 @@ Sets the specified `slot` in the storage of the given `self` address to the prov #### **`setNonce(address self, uint64 n) → (address)`** -Sets the nonce of the given `self` address to the provided value `n`. +Sets the nonce of the given `self` address to the provided value `n`. It will revert if the new +nonce is lower than the current address nonce. + +#### **`setNonceUnsafe(address self, uint64 n) → (address)`** + +Sets the nonce of the given `self` address to the provided arbitrary value `n`. #### **`impersonateOnce(address self) → (address)`** diff --git a/docs/src/reference/modules/context.md b/docs/src/reference/modules/context.md index 68809685..e25f1ffa 100644 --- a/docs/src/reference/modules/context.md +++ b/docs/src/reference/modules/context.md @@ -57,6 +57,14 @@ sets the `block.basefee` to `baseFee` sets the `block.basefee` to `baseFee` +#### **`setBlockPrevrandao(Context self, bytes32 newPrevrandao) → (Context)`** + +sets the `block.prevrandao` to `newPrevrandao` + +#### **`setBlockPrevrandao(bytes32 newPrevrandao) → (Context)`** + +sets the `block.prevrandao` to `newPrevrandao` + #### **`setChainId(Context self, uint64 chainId) → (Context)`** sets the `block.chainid` to `chainId` @@ -73,6 +81,14 @@ Sets the block coinbase to `who`. Sets the block coinbase to `who`. +#### **`setGasPrice(Context self, address newGasPrice) → (Context)`** + +Sets the gas price to `newGasPrice`. + +#### **`setGasPrice(address newGasPrice) → (Context)`** + +Sets the gas price to `newGasPrice`. + #### **`expectRevert(bytes revertData)`** Function used to check whether the next call reverts or not. @@ -113,6 +129,22 @@ Used to check if a call to `callee` with `data` was made. Used to check if a call to `callee` with `data` and `msgValue` was made. +#### **`expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data)`** + +Expect a call from `callee` with the specified `msgValue` and `data`, and a minimum amount of gas `minGas`. + +#### **`expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data, uint64 count)`** + +Expect a number of calls `count` from `callee` with the specified `msgValue` and `data`, and a minimum amount of gas `minGas`. + +#### **`expectSafeMemory(uint64 min, uint64 max)`** + +Allows to write on memory only between [0x00, 0x60) and [`min`, `max`) in the current subcontext + +#### **`expectsafememorycall(uint64 min, uint64 max)`** + +Allows to write on memory only between [0x00, 0x60) and [`min`, `max`) in the next subcontext + #### **`snapshot(Context) → (uint256)`** Takes a snapshot of the current state of the vm and returns an identifier. @@ -129,3 +161,19 @@ Reverts the state of the vm to the snapshot with id `snapshotId`. Reverts the state of the vm to the snapshot with id `snapshotId`. +#### **`addBreakpoint(Context self, string memory name)`** + +Creates a breakpoint to jump to in the debugger with `name`. + +#### **`addBreakpoint(string memory name)`** + +Creates a breakpoint to jump to in the debugger with `name`. + +#### **`addConditionalBreakpoint(Context self, string memory name, bool condition)`** + +Creates a conditional breakpoint to jump to in the debugger with name `name` and condition `condition`. + +#### **`addConditionalBreakpoint(string memory name, bool condition)`** + +Creates a conditional breakpoint to jump to in the debugger with name `name` and condition `condition`. +