Skip to content

Commit

Permalink
fix: move cheats, improve docs (#256)
Browse files Browse the repository at this point in the history
* fix: move some cheats

* fix: move cheats, bases

* docs: remove suggestions
  • Loading branch information
ZeroEkkusu authored Dec 16, 2022
1 parent c12c6ad commit eb980e1
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 61 deletions.
15 changes: 10 additions & 5 deletions src/Common.sol → src/Base.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,30 @@
pragma solidity >=0.6.2 <0.9.0;

import {StdStorage} from "./StdStorage.sol";
import {Vm} from "./Vm.sol";
import {Vm, VmSafe} from "./Vm.sol";

abstract contract CommonBase {
// Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D.
address internal constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code"))));

// console.sol and console2.sol work by executing a staticcall to this address.
address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67;

// Default address for tx.origin and msg.sender, 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38.
address internal constant DEFAULT_SENDER = address(uint160(uint256(keccak256("foundry default caller"))));

// Address of the test contract, deployed by the DEFAULT_SENDER.
address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f;

uint256 internal constant UINT256_MAX =
115792089237316195423570985008687907853269984665640564039457584007913129639935;

Vm internal constant vm = Vm(VM_ADDRESS);

StdStorage internal stdstore;
}

abstract contract TestBase is CommonBase {}

abstract contract ScriptBase is CommonBase {
// Used when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.
address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;

VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS);
}
16 changes: 9 additions & 7 deletions src/Script.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.9.0;

import {CommonBase} from "./Common.sol";
// 💬 ABOUT
// Standard Library's default Script.

// 🧩 MODULES
import {ScriptBase} from "./Base.sol";
import {console} from "./console.sol";
import {console2} from "./console2.sol";
import {StdChains} from "./StdChains.sol";
Expand All @@ -12,13 +16,11 @@ import {StdStorage, stdStorageSafe} from "./StdStorage.sol";
import {StdUtils} from "./StdUtils.sol";
import {VmSafe} from "./Vm.sol";

abstract contract ScriptBase is CommonBase {
// Create2 factory used by scripts when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.
address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;

VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS);
}
// 📦 BOILERPLATE
import {ScriptBase} from "./Base.sol";

// ⭐️ SCRIPT
abstract contract Script is StdChains, StdCheatsSafe, StdUtils, ScriptBase {
// Note: IS_SCRIPT() must return true.
bool public IS_SCRIPT = true;
}
86 changes: 43 additions & 43 deletions src/StdCheats.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ pragma solidity >=0.6.2 <0.9.0;
pragma experimental ABIEncoderV2;

import {StdStorage, stdStorage} from "./StdStorage.sol";
import {Vm, VmSafe} from "./Vm.sol";
import {Vm} from "./Vm.sol";

abstract contract StdCheatsSafe {
VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code")))));
Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code")))));

bool private gasMeteringOff;

// Data structures to parse Transaction objects from the broadcast artifact
// that conform to EIP1559. The Raw structs is what is parsed from the JSON
Expand Down Expand Up @@ -422,6 +424,45 @@ abstract contract StdCheatsSafe {
require(b.length <= 32, "StdCheats _bytesToUint(bytes): Bytes length exceeds 32.");
return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256));
}

function isFork() internal virtual returns (bool status) {
try vm.activeFork() {
status = true;
} catch (bytes memory) {}
}

modifier skipWhenForking() {
if (!isFork()) {
_;
}
}

modifier skipWhenNotForking() {
if (isFork()) {
_;
}
}

modifier noGasMetering() {
vm.pauseGasMetering();
// To prevent turning gas monitoring back on with nested functions that use this modifier,
// we check if gasMetering started in the off position. If it did, we don't want to turn
// it back on until we exit the top level function that used the modifier
//
// i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well.
// funcA will have `gasStartedOff` as false, funcB will have it as true,
// so we only turn metering back on at the end of the funcA
bool gasStartedOff = gasMeteringOff;
gasMeteringOff = true;

_;

// if gas metering was on when this modifier was called, turn it back on at the end
if (!gasStartedOff) {
gasMeteringOff = false;
vm.resumeGasMetering();
}
}
}

// Wrappers around cheatcodes to avoid footguns
Expand All @@ -431,8 +472,6 @@ abstract contract StdCheats is StdCheatsSafe {
StdStorage private stdstore;
Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code")))));

bool private gasMeteringOff;

// Skip forward or rewind time by the specified number of seconds
function skip(uint256 time) internal virtual {
vm.warp(block.timestamp + time);
Expand Down Expand Up @@ -523,43 +562,4 @@ abstract contract StdCheats is StdCheatsSafe {
stdstore.target(token).sig(0x18160ddd).checked_write(totSup);
}
}

function isFork() internal virtual returns (bool status) {
try vm.activeFork() {
status = true;
} catch (bytes memory) {}
}

modifier noGasMetering() {
vm.pauseGasMetering();
// To prevent turning gas monitoring back on with nested functions that use this modifier,
// we check if gasMetering started in the off position. If it did, we don't want to turn
// it back on until we exit the top level function that used the modifier
//
// i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well.
// funcA will have `gasStartedOff` as false, funcB will have it as true,
// so we only turn metering back on at the end of the funcA
bool gasStartedOff = gasMeteringOff;
gasMeteringOff = true;

_;

// if gas metering was on when this modifier was called, turn it back on at the end
if (!gasStartedOff) {
gasMeteringOff = false;
vm.resumeGasMetering();
}
}

modifier skipWhenForking() {
if (!isFork()) {
_;
}
}

modifier skipWhenNotForking() {
if (isFork()) {
_;
}
}
}
6 changes: 4 additions & 2 deletions src/StdUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
pragma solidity >=0.6.2 <0.9.0;

// TODO Remove import.
import {Vm} from "./Vm.sol";
import {VmSafe} from "./Vm.sol";

abstract contract StdUtils {
Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code")))));
VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code")))));
address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67;

uint256 private constant INT256_MIN_ABS =
Expand Down Expand Up @@ -109,6 +109,8 @@ abstract contract StdUtils {
return address(uint160(uint256(bytesValue)));
}

// Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere.

function console2_log(string memory p0, uint256 p1) private view {
(bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string,uint256)", p0, p1));
status;
Expand Down
16 changes: 12 additions & 4 deletions src/Test.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.9.0;

import {CommonBase} from "./Common.sol";
import {DSTest} from "ds-test/test.sol";
// 💬 ABOUT
// Standard Library's default Test

// 🧩 MODULES
import {console} from "./console.sol";
import {console2} from "./console2.sol";
import {StdAssertions} from "./StdAssertions.sol";
Expand All @@ -15,6 +17,12 @@ import {StdStorage, stdStorage} from "./StdStorage.sol";
import {StdUtils} from "./StdUtils.sol";
import {Vm} from "./Vm.sol";

abstract contract TestBase is CommonBase {}
// 📦 BOILERPLATE
import {TestBase} from "./Base.sol";
import {DSTest} from "ds-test/test.sol";

abstract contract Test is DSTest, StdAssertions, StdChains, StdCheats, StdUtils, TestBase {}
// ⭐️ TEST
abstract contract Test is DSTest, StdAssertions, StdChains, StdCheats, StdUtils, TestBase {
// Note: IS_TEST() must return true.
// Note: Must have failure system, https://github.com/dapphub/ds-test/blob/cd98eff28324bfac652e63a239a60632a761790b/src/test.sol#L39-L76.
}

0 comments on commit eb980e1

Please sign in to comment.