// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.9.0; pragma experimental ABIEncoderV2; // Cheatcodes are marked as view/pure/none using the following rules: // 0. A call's observable behaviour includes its return value, logs, reverts and state writes, // 1. If you can influence a later call's observable behaviour, you're neither `view` nor `pure (you are modifying some state be it the EVM, interpreter, filesystem, etc), // 2. Otherwise if you can be influenced by an earlier call, or if reading some state, you're `view`, // 3. Otherwise you're `pure`. interface VmSafe { struct Log { bytes32[] topics; bytes data; address emitter; } struct Rpc { string key; string url; } struct FsMetadata { bool isDir; bool isSymlink; uint256 length; bool readOnly; uint256 modified; uint256 accessed; uint256 created; } // Loads a storage slot from an address function load(address target, bytes32 slot) external view returns (bytes32 data); // Signs data function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); // Gets the address for a given private key function addr(uint256 privateKey) external pure returns (address keyAddr); // Gets the nonce of an account function getNonce(address account) external view returns (uint64 nonce); // Performs a foreign function call via the terminal function ffi(string[] calldata commandInput) external returns (bytes memory result); // Sets environment variables function setEnv(string calldata name, string calldata value) external; // Reads environment variables, (name) => (value) function envBool(string calldata name) external view returns (bool value); function envUint(string calldata name) external view returns (uint256 value); function envInt(string calldata name) external view returns (int256 value); function envAddress(string calldata name) external view returns (address value); function envBytes32(string calldata name) external view returns (bytes32 value); function envString(string calldata name) external view returns (string memory value); function envBytes(string calldata name) external view returns (bytes memory value); // Reads environment variables as arrays function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value); function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value); function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value); function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value); function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value); function envString(string calldata name, string calldata delim) external view returns (string[] memory value); function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value); // Read environment variables with default value function envOr(string calldata name, bool defaultValue) external returns (bool value); function envOr(string calldata name, uint256 defaultValue) external returns (uint256 value); function envOr(string calldata name, int256 defaultValue) external returns (int256 value); function envOr(string calldata name, address defaultValue) external returns (address value); function envOr(string calldata name, bytes32 defaultValue) external returns (bytes32 value); function envOr(string calldata name, string calldata defaultValue) external returns (string memory value); function envOr(string calldata name, bytes calldata defaultValue) external returns (bytes memory value); // Read environment variables as arrays with default value function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue) external returns (bool[] memory value); function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue) external returns (uint256[] memory value); function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue) external returns (int256[] memory value); function envOr(string calldata name, string calldata delim, address[] calldata defaultValue) external returns (address[] memory value); function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue) external returns (bytes32[] memory value); function envOr(string calldata name, string calldata delim, string[] calldata defaultValue) external returns (string[] memory value); function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue) external returns (bytes[] memory value); // Records all storage reads and writes function record() external; // Gets all accessed reads and write slot from a recording session, for a given address function accesses(address target) external returns (bytes32[] memory readSlots, bytes32[] memory writeSlots); // Gets the _creation_ bytecode from an artifact file. Takes in the relative path to the json file function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode); // Gets the _deployed_ bytecode from an artifact file. Takes in the relative path to the json file function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode); // Labels an address in call traces function label(address account, string calldata newLabel) external; // Using the address that calls the test contract, has the next call (at this call depth only) create a transaction that can later be signed and sent onchain function broadcast() external; // Has the next call (at this call depth only) create a transaction with the address provided as the sender that can later be signed and sent onchain function broadcast(address signer) external; // Has the next call (at this call depth only) create a transaction with the private key provided as the sender that can later be signed and sent onchain function broadcast(uint256 privateKey) external; // Using the address that calls the test contract, has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain function startBroadcast() external; // Has all subsequent calls (at this call depth only) create transactions with the address provided that can later be signed and sent onchain function startBroadcast(address signer) external; // Has all subsequent calls (at this call depth only) create transactions with the private key provided that can later be signed and sent onchain function startBroadcast(uint256 privateKey) external; // Stops collecting onchain transactions function stopBroadcast() external; // Reads the entire content of file to string function readFile(string calldata path) external view returns (string memory data); // Reads the entire content of file as binary. Path is relative to the project root. function readFileBinary(string calldata path) external view returns (bytes memory data); // Get the path of the current project root function projectRoot() external view returns (string memory path); // Get the metadata for a file/directory function fsMetadata(string calldata fileOrDir) external returns (FsMetadata memory metadata); // Reads next line of file to string function readLine(string calldata path) external view returns (string memory line); // Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does. function writeFile(string calldata path, string calldata data) external; // Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does. // Path is relative to the project root. function writeFileBinary(string calldata path, bytes calldata data) external; // Writes line to file, creating a file if it does not exist. function writeLine(string calldata path, string calldata data) external; // Closes file for reading, resetting the offset and allowing to read it from beginning with readLine. function closeFile(string calldata path) external; // Removes file. This cheatcode will revert in the following situations, but is not limited to just these cases: // - Path points to a directory. // - The file doesn't exist. // - The user lacks permissions to remove the file. function removeFile(string calldata path) external; // Convert values to a string function toString(address value) external pure returns (string memory stringifiedValue); function toString(bytes calldata value) external pure returns (string memory stringifiedValue); function toString(bytes32 value) external pure returns (string memory stringifiedValue); function toString(bool value) external pure returns (string memory stringifiedValue); function toString(uint256 value) external pure returns (string memory stringifiedValue); function toString(int256 value) external pure returns (string memory stringifiedValue); // Convert values from a string function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue); function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue); function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue); function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue); function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue); function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue); // Record all the transaction logs function recordLogs() external; // Gets all the recorded logs function getRecordedLogs() external returns (Log[] memory logs); // Derive a private key from a provided mnenomic string (or mnenomic file path) at the derivation path m/44'/60'/0'/0/{index} function deriveKey(string calldata mnemonic, uint32 index) external pure returns (uint256 privateKey); // Derive a private key from a provided mnenomic string (or mnenomic file path) at {derivationPath}{index} function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index) external pure returns (uint256 privateKey); // Adds a private key to the local forge wallet and returns the address function rememberKey(uint256 privateKey) external returns (address keyAddr); // // parseJson // // ---- // In case the returned value is a JSON object, it's encoded as a ABI-encoded tuple. As JSON objects // don't have the notion of ordered, but tuples do, they JSON object is encoded with it's fields ordered in // ALPHABETICAL order. That means that in order to successfully decode the tuple, we need to define a tuple that // encodes the fields in the same order, which is alphabetical. In the case of Solidity structs, they are encoded // as tuples, with the attributes in the order in which they are defined. // For example: json = { 'a': 1, 'b': 0xa4tb......3xs} // a: uint256 // b: address // To decode that json, we need to define a struct or a tuple as follows: // struct json = { uint256 a; address b; } // If we defined a json struct with the opposite order, meaning placing the address b first, it would try to // decode the tuple in that order, and thus fail. // ---- // Given a string of JSON, return it as ABI-encoded function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData); function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData); // The following parseJson cheatcodes will do type coercion, for the type that they indicate. // For example, parseJsonUint will coerce all values to a uint256. That includes stringified numbers '12' // and hex numbers '0xEF'. // Type coercion works ONLY for discrete values or arrays. That means that the key must return a value or array, not // a JSON object. function parseJsonUint(string calldata, string calldata) external returns (uint256); function parseJsonUintArray(string calldata, string calldata) external returns (uint256[] memory); function parseJsonInt(string calldata, string calldata) external returns (int256); function parseJsonIntArray(string calldata, string calldata) external returns (int256[] memory); function parseJsonBool(string calldata, string calldata) external returns (bool); function parseJsonBoolArray(string calldata, string calldata) external returns (bool[] memory); function parseJsonAddress(string calldata, string calldata) external returns (address); function parseJsonAddressArray(string calldata, string calldata) external returns (address[] memory); function parseJsonString(string calldata, string calldata) external returns (string memory); function parseJsonStringArray(string calldata, string calldata) external returns (string[] memory); function parseJsonBytes(string calldata, string calldata) external returns (bytes memory); function parseJsonBytesArray(string calldata, string calldata) external returns (bytes[] memory); function parseJsonBytes32(string calldata, string calldata) external returns (bytes32); function parseJsonBytes32Array(string calldata, string calldata) external returns (bytes32[] memory); // Serialize a key and value to a JSON object stored in-memory that can be later written to a file // It returns the stringified version of the specific JSON file up to that moment. function serializeBool(string calldata objectKey, string calldata valueKey, bool value) external returns (string memory json); function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value) external returns (string memory json); function serializeInt(string calldata objectKey, string calldata valueKey, int256 value) external returns (string memory json); function serializeAddress(string calldata objectKey, string calldata valueKey, address value) external returns (string memory json); function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value) external returns (string memory json); function serializeString(string calldata objectKey, string calldata valueKey, string calldata value) external returns (string memory json); function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value) external returns (string memory json); function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values) external returns (string memory json); function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values) external returns (string memory json); function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values) external returns (string memory json); function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values) external returns (string memory json); function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values) external returns (string memory json); function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values) external returns (string memory json); function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values) external returns (string memory json); // // writeJson // // ---- // Write a serialized JSON object to a file. If the file exists, it will be overwritten. // Let's assume we want to write the following JSON to a file: // // { "boolean": true, "number": 342, "object": { "title": "finally json serialization" } } // // ``` // string memory json1 = "some key"; // vm.serializeBool(json1, "boolean", true); // vm.serializeBool(json1, "number", uint256(342)); // json2 = "some other key"; // string memory output = vm.serializeString(json2, "title", "finally json serialization"); // string memory finalJson = vm.serialize(json1, "object", output); // vm.writeJson(finalJson, "./output/example.json"); // ``` // The critical insight is that every invocation of serialization will return the stringified version of the JSON // up to that point. That means we can construct arbitrary JSON objects and then use the return stringified version // to serialize them as values to another JSON object. // // json1 and json2 are simply keys used by the backend to keep track of the objects. So vm.serializeJson(json1,..) // will find the object in-memory that is keyed by "some key". function writeJson(string calldata json, string calldata path) external; // Write a serialized JSON object to an **existing** JSON file, replacing a value with key = // This is useful to replace a specific value of a JSON file, without having to parse the entire thing function writeJson(string calldata json, string calldata path, string calldata valueKey) external; // Returns the RPC url for the given alias function rpcUrl(string calldata rpcAlias) external view returns (string memory json); // Returns all rpc urls and their aliases `[alias, url][]` function rpcUrls() external view returns (string[2][] memory urls); // Returns all rpc urls and their aliases as structs. function rpcUrlStructs() external view returns (Rpc[] memory urls); // If the condition is false, discard this run's fuzz inputs and generate new ones. function assume(bool condition) external pure; // Pauses gas metering (i.e. gas usage is not counted). Noop if already paused. function pauseGasMetering() external; // Resumes gas metering (i.e. gas usage is counted again). Noop if already on. function resumeGasMetering() external; // Writes a breakpoint to jump to in the debugger function breakpoint(string calldata char) external; // Writes a conditional breakpoint to jump to in the debugger function breakpoint(string calldata char, bool value) external; } interface Vm is VmSafe { // Sets block.timestamp function warp(uint256 newTimestamp) external; // Sets block.height function roll(uint256 newHeight) external; // Sets block.basefee function fee(uint256 newBasefee) external; // Sets block.difficulty function difficulty(uint256 newDifficulty) external; // Sets block.chainid function chainId(uint256 newChainId) external; // Sets tx.gasprice function txGasPrice(uint256 newGasPrice) external; // Stores a value to an address' storage slot. function store(address target, bytes32 slot, bytes32 value) external; // Sets the nonce of an account; must be higher than the current nonce of the account function setNonce(address account, uint64 newNonce) external; // Sets the *next* call's msg.sender to be the input address function prank(address msgSender) external; // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called function startPrank(address msgSender) external; // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input function prank(address msgSender, address txOrigin) external; // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input function startPrank(address msgSender, address txOrigin) external; // Resets subsequent calls' msg.sender to be `address(this)` function stopPrank() external; // Sets an address' balance function deal(address account, uint256 newBalance) external; // Sets an address' code function etch(address target, bytes calldata newRuntimeBytecode) external; // Expects an error on next call function expectRevert(bytes calldata revertData) external; function expectRevert(bytes4 revertData) external; function expectRevert() external; // Prepare an expected log with all four checks enabled. // Call this function, then emit an event, then call a function. Internally after the call, we check if // logs were emitted in the expected order with the expected topics and data. // Second form also checks supplied address against emitting contract. function expectEmit() external; function expectEmit(address emitter) external; // Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData). // Call this function, then emit an event, then call a function. Internally after the call, we check if // logs were emitted in the expected order with the expected topics and data (as specified by the booleans). // Second form also checks supplied address against emitting contract. function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) external; function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter) external; // Mocks a call to an address, returning specified data. // Calldata can either be strict or a partial match, e.g. if you only // pass a Solidity selector to the expected calldata, then the entire Solidity // function will be mocked. function mockCall(address callee, bytes calldata data, bytes calldata returnData) external; // Mocks a call to an address with a specific msg.value, returning specified data. // Calldata match takes precedence over msg.value in case of ambiguity. function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external; // Reverts a call to an address with specified revert data. function mockCallRevert(address callee, bytes calldata data, bytes calldata revertData) external; // Reverts a call to an address with a specific msg.value, with specified revert data. function mockCallRevert(address callee, uint256 msgValue, bytes calldata data, bytes calldata revertData) external; // Clears all mocked calls function clearMockedCalls() external; // Expects a call to an address with the specified calldata. // Calldata can either be a strict or a partial match function expectCall(address callee, bytes calldata data) external; // Expects given number of calls to an address with the specified calldata. function expectCall(address callee, bytes calldata data, uint64 count) external; // Expects a call to an address with the specified msg.value and calldata function expectCall(address callee, uint256 msgValue, bytes calldata data) external; // Expects given number of calls to an address with the specified msg.value and calldata function expectCall(address callee, uint256 msgValue, bytes calldata data, uint64 count) external; // Expect a call to an address with the specified msg.value, gas, and calldata. function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data) external; // Expects given number of calls to an address with the specified msg.value, gas, and calldata. function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data, uint64 count) external; // Expect a call to an address with the specified msg.value and calldata, and a *minimum* amount of gas. function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) external; // Expect given number of calls to an address with the specified msg.value and calldata, and a *minimum* amount of gas. function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data, uint64 count) external; // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the current subcontext. If any other // memory is written to, the test will fail. Can be called multiple times to add more ranges to the set. function expectSafeMemory(uint64 min, uint64 max) external; // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the next created subcontext. // If any other memory is written to, the test will fail. Can be called multiple times to add more ranges // to the set. function expectSafeMemoryCall(uint64 min, uint64 max) external; // Sets block.coinbase function coinbase(address newCoinbase) external; // Snapshot the current state of the evm. // Returns the id of the snapshot that was created. // To revert a snapshot use `revertTo` function snapshot() external returns (uint256 snapshotId); // Revert the state of the EVM to a previous snapshot // Takes the snapshot id to revert to. // This deletes the snapshot and all snapshots taken after the given snapshot id. function revertTo(uint256 snapshotId) external returns (bool success); // Creates a new fork with the given endpoint and block and returns the identifier of the fork function createFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); // Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork function createFork(string calldata urlOrAlias) external returns (uint256 forkId); // Creates a new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before the transaction, // and returns the identifier of the fork function createFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); // Creates _and_ also selects a new fork with the given endpoint and block and returns the identifier of the fork function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); // Creates _and_ also selects new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before // the transaction, returns the identifier of the fork function createSelectFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); // Creates _and_ also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId); // Takes a fork identifier created by `createFork` and sets the corresponding forked state as active. function selectFork(uint256 forkId) external; /// Returns the identifier of the currently active fork. Reverts if no fork is currently active. function activeFork() external view returns (uint256 forkId); // Updates the currently active fork to given block number // This is similar to `roll` but for the currently active fork function rollFork(uint256 blockNumber) external; // Updates the currently active fork to given transaction // this will `rollFork` with the number of the block the transaction was mined in and replays all transaction mined before it in the block function rollFork(bytes32 txHash) external; // Updates the given fork to given block number function rollFork(uint256 forkId, uint256 blockNumber) external; // Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block function rollFork(uint256 forkId, bytes32 txHash) external; // Marks that the account(s) should use persistent storage across fork swaps in a multifork setup // Meaning, changes made to the state of this account will be kept when switching forks function makePersistent(address account) external; function makePersistent(address account0, address account1) external; function makePersistent(address account0, address account1, address account2) external; function makePersistent(address[] calldata accounts) external; // Revokes persistent status from the address, previously added via `makePersistent` function revokePersistent(address account) external; function revokePersistent(address[] calldata accounts) external; // Returns true if the account is marked as persistent function isPersistent(address account) external view returns (bool persistent); // In forking mode, explicitly grant the given address cheatcode access function allowCheatcodes(address account) external; // Fetches the given transaction from the active fork and executes it on the current state function transact(bytes32 txHash) external; // Fetches the given transaction from the given fork and executes it on the current state function transact(uint256 forkId, bytes32 txHash) external; }