// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.9.0; pragma experimental ABIEncoderV2; interface Vm { struct Log { bytes32[] topics; bytes data; } // Sets block.timestamp (newTimestamp) function warp(uint256) external; // Sets block.height (newHeight) function roll(uint256) external; // Sets block.basefee (newBasefee) function fee(uint256) external; // Sets block.difficulty (newDifficulty) function difficulty(uint256) external; // Sets block.chainid function chainId(uint256) external; // Loads a storage slot from an address (who, slot) function load(address,bytes32) external returns (bytes32); // Stores a value to an address' storage slot, (who, slot, value) function store(address,bytes32,bytes32) external; // Signs data, (privateKey, digest) => (v, r, s) function sign(uint256,bytes32) external returns (uint8,bytes32,bytes32); // Gets the address for a given private key, (privateKey) => (address) function addr(uint256) external returns (address); // Gets the nonce of an account function getNonce(address) external returns (uint64); // Sets the nonce of an account; must be higher than the current nonce of the account function setNonce(address, uint64) external; // Performs a foreign function call via the terminal, (stringInputs) => (result) function ffi(string[] calldata) external returns (bytes memory); // Sets environment variables, (name, value) function setEnv(string calldata, string calldata) external; // Reads environment variables, (name) => (value) function envBool(string calldata) external returns (bool); function envUint(string calldata) external returns (uint256); function envInt(string calldata) external returns (int256); function envAddress(string calldata) external returns (address); function envBytes32(string calldata) external returns (bytes32); function envString(string calldata) external returns (string memory); function envBytes(string calldata) external returns (bytes memory); // Reads environment variables as arrays, (name, delim) => (value[]) function envBool(string calldata, string calldata) external returns (bool[] memory); function envUint(string calldata, string calldata) external returns (uint256[] memory); function envInt(string calldata, string calldata) external returns (int256[] memory); function envAddress(string calldata, string calldata) external returns (address[] memory); function envBytes32(string calldata, string calldata) external returns (bytes32[] memory); function envString(string calldata, string calldata) external returns (string[] memory); function envBytes(string calldata, string calldata) external returns (bytes[] memory); // Sets the *next* call's msg.sender to be the input address function prank(address) external; // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called function startPrank(address) 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,address) 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,address) external; // Resets subsequent calls' msg.sender to be `address(this)` function stopPrank() external; // Sets an address' balance, (who, newBalance) function deal(address, uint256) external; // Sets an address' code, (who, newCode) function etch(address, bytes calldata) external; // Expects an error on next call function expectRevert(bytes calldata) external; function expectRevert(bytes4) external; function expectRevert() external; // 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) external returns (bytes32[] memory reads, bytes32[] memory writes); // 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) function expectEmit(bool,bool,bool,bool) external; function expectEmit(bool,bool,bool,bool,address) 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,bytes calldata,bytes calldata) 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,uint256,bytes calldata,bytes calldata) 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,bytes calldata) external; // Expects a call to an address with the specified msg.value and calldata function expectCall(address,uint256,bytes calldata) external; // Gets the code from an artifact file. Takes in the relative path to the json file function getCode(string calldata) external returns (bytes memory); // Labels an address in call traces function label(address, string calldata) external; // If the condition is false, discard this run's fuzz inputs and generate new ones function assume(bool) external; // Sets block.coinbase (who) function coinbase(address) 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) 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 that can later be signed and sent onchain function startBroadcast(address) external; // Stops collecting onchain transactions function stopBroadcast() external; // Reads the entire content of file to string, (path) => (data) function readFile(string calldata) external returns (string memory); // Get the path of the current project root function projectRoot() external returns (string memory); // Reads next line of file to string, (path) => (line) function readLine(string calldata) external returns (string memory); // Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does. // (path, data) => () function writeFile(string calldata, string calldata) external; // Writes line to file, creating a file if it does not exist. // (path, data) => () function writeLine(string calldata, string calldata) external; // Closes file for reading, resetting the offset and allowing to read it from beginning with readLine. // (path) => () function closeFile(string calldata) 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. // (path) => () function removeFile(string calldata) external; // Convert values to a string, (value) => (stringified value) function toString(address) external returns(string memory); function toString(bytes calldata) external returns(string memory); function toString(bytes32) external returns(string memory); function toString(bool) external returns(string memory); function toString(uint256) external returns(string memory); function toString(int256) external returns(string memory); // Convert values from a string, (string) => (parsed value) function parseBytes(string calldata) external returns (bytes memory); function parseAddress(string calldata) external returns (address); function parseUint(string calldata) external returns (uint256); function parseInt(string calldata) external returns (int256); function parseBytes32(string calldata) external returns (bytes32); function parseBool(string calldata) external returns (bool); // Record all the transaction logs function recordLogs() external; // Gets all the recorded logs, () => (logs) function getRecordedLogs() external returns (Log[] memory); // 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); // 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) external returns(bool); // Creates a new fork with the given endpoint and block and returns the identifier of the fork function createFork(string calldata,uint256) external returns(uint256); // Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork function createFork(string calldata) external returns(uint256); // Creates _and_ also selects a new fork with the given endpoint and block and returns the identifier of the fork function createSelectFork(string calldata,uint256) external returns(uint256); // 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) external returns(uint256); // Takes a fork identifier created by `createFork` and sets the corresponding forked state as active. function selectFork(uint256) external; /// Returns the currently active fork /// Reverts if no fork is currently active function activeFork() external returns(uint256); // Updates the currently active fork to given block number // This is similar to `roll` but for the currently active fork function rollFork(uint256) external; // Updates the given fork to given block number function rollFork(uint256 forkId, uint256 blockNumber) 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) external; function makePersistent(address, address) external; function makePersistent(address, address, address) external; function makePersistent(address[] calldata) external; // Revokes persistent status from the address, previously added via `makePersistent` function revokePersistent(address) external; function revokePersistent(address[] calldata) external; // Returns true if the account is marked as persistent function isPersistent(address) external returns (bool); // Returns the RPC url for the given alias function rpcUrl(string calldata) external returns(string memory); // Returns all rpc urls and their aliases `[alias, url][]` function rpcUrls() external returns(string[2][] memory); // 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, uint32) external returns (uint256); // Derive a private key from a provided mnenomic string (or mnenomic file path) at the derivation path {path}{index} function deriveKey(string calldata, string calldata, uint32) external returns (uint256); // parseJson // Given a string of JSON, return the ABI-encoded value of provided key // (stringified json, key) => (ABI-encoded data) // Read the note below! function parseJson(string calldata, string calldata) external returns(bytes memory); // Given a string of JSON, return it as ABI-encoded, (stringified json, key) => (ABI-encoded data) // Read the note below! function parseJson(string calldata) external returns(bytes memory); // Note: // ---- // 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 ordser. That means that in order to succesfully 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. }