> For the complete documentation index, see [llms.txt](https://docs.eridian.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.eridian.xyz/ethereum-dev/foundry-notes/tests/cheatcodes.md).

# Cheatcodes

To manipulate the state of the blockchain, as well as test for specific reverts and events, Foundry is shipped with a set of cheatcodes.

Cheatcodes are accessed using the `vm` instance available in Forge Standard Library's `Test` contract.

## prank

Sets `msg.sender` to the specified address **for the next call**. "The next call" includes static calls as well, but not calls to the cheat code address.

If the alternative signature of `prank` is used, then `tx.origin` is set as well for the next call.

{% code title="prank example" %}

```solidity
/// function withdraw() public {
///     require(msg.sender == owner);

vm.prank(owner);
myContract.withdraw(); // [PASS]
```

{% endcode %}

## startPrank

Sets `msg.sender` **for all subsequent calls** until [`stopPrank`](https://book.getfoundry.sh/cheatcodes/stop-prank.html) is called.

If the alternative signature of `startPrank` is used, then `tx.origin` is set as well for all subsequent calls.

{% code title="startPrank example" %}

```solidity
function startPrank(address) external;
function startPrank(address sender, address origin) external;
```

{% endcode %}

## stopPrank

Stops an active prank started by [`startPrank`](https://book.getfoundry.sh/cheatcodes/start-prank.html), resetting `msg.sender` and `tx.origin` to the values before `startPrank` was called.

{% code title="startPrank example" %}

```solidity
function stopPrank() external;
```

{% endcode %}

## deal

Sets the balance of an address `who` to `newBalance`.

```solidity
function deal(address who, uint256 newBalance) external;

vm.deal(alice, 1 ether);
```

## hoax

Similar to `prank` + `deal` except that it adds to the existing user's balance where `deal` resets the balance to the specified amount.

```solidity
function hoax(address who, uint256 give) public;
```

## txGasPrice

Sets `tx.gasprice` for the rest of the transaction.

{% code title="txGasPrice example" %}

```solidity
function txGasPrice(uint256) external;
function txGasPrice(uint256 newGasPrice) external;

// Example usage
uint256 gasStart = gasleft();
vm.txGasPrice(GAS_PRICE);
// ...Do things...
uint256 gasEnd = gasleft();
uint256 gasUsed = (gasStart - gasEnd) * GAS_PRICE;
console.log("Gas used: ", gasUsed);
```

{% endcode %}

## warp

Sets `block.timestamp`

```solidity
vm.warp(1641070800);
emit log_uint(block.timestamp); // 1641070800
```

## roll

Sets `block.number`.

```solidity
vm.roll(100);
emit log_uint(block.number); // 100
```

## recordLogs

Tells the VM to start recording all the emitted events. To access them, use `getRecordedLogs`.

{% code fullWidth="false" %}

```solidity
vm.recordLogs();                                // Start recording logs
raffle.performUpkeep("");                       // Call function that emits event log
Vm.Log[] memory entries = vm.getRecordedLogs(); // Store emitted log

// Access stored log by knowing exactly which logs are emitted
// .topics[0] would refer to the entire event
// .topics[1] is for the first actual topic
// All logs are recorded as bytes32 in foundry
bytes32 requestId = entries[1].topics[1];       
```

{% endcode %}

## expectEmit

Assert a specific log is emitted during the next call.

```solidity
function expectEmit() external;
function expectEmit(
    bool checkTopic1,
    bool checkTopic2,
    bool checkTopic3,
    bool checkData
) external;

function expectEmit(address emitter) external;
function expectEmit(
    bool checkTopic1,
    bool checkTopic2,
    bool checkTopic3,
    bool checkData,
    address emitter
) external;
```

1. Call the cheat code, specifying whether we should check the first, second or third topic, and the log data (`expectEmit``()` checks them all). Topic 0 is always checked.
2. Emit the event we are supposed to see during the next call.
3. Perform the call.

You can perform steps 1 and 2 multiple times to match a *sequence* of events in the next call.

If the event is not available in the current scope (e.g. if we are using an interface, or an external smart contract), we can define the event ourselves with an identical event signature.

There are 2 varieties of `expectEmit`:

* **Without checking the emitter address**: Asserts the topics match **without** checking the emitting address.
* **With `address`**: Asserts the topics match and that the emitting address matches.

{% hint style="info" %}
**Matching sequences**

In functions that emit a lot of events, it's possible to "skip" events and only match a specific sequence, but this sequence must always be in order. As an example, let's say a function emits events: `A, B, C, D, E, F, F, G`.

`expectEmit` will be able to match ranges with and without skipping events in between:

* `[A, B, C]` is valid.
* `[B, D, F]` is valid.
* `[G]` or any other single event combination is valid.
* `[B, A]` or similar out-of-order combinations are **invalid** (events must be in order).
* `[C, F, F]` is valid.
* `[F, F, C]` is **invalid** (out of order).
  {% endhint %}

### expectEmit Examples

{% code title="Just check that an event happens but no details about it" fullWidth="true" %}

```solidity
// The first parameter: Whether to check the event signature.
// The second parameter: Whether to check the indexed parameters (topics) of the event.
// The third parameter: Whether to check the unindexed parameters (data) of the event.
// The fourth parameter: Whether to check the event data's values.
vm.expectEmit(true, true, true, false); // `false` for data means we don't care about the value
emit IAavePM.Rebalanced(0); // The data is a placeholder and not checked
```

{% endcode %}

{% code title="This does not check the emitting address." fullWidth="true" %}

```solidity
event Transfer(address indexed from, address indexed to, uint256 amount);

function testERC20EmitsTransfer() public {
    vm.expectEmit();

    // We emit the event we expect to see.
    emit MyToken.Transfer(address(this), address(1), 10);

    // We perform the call.
    myToken.transfer(address(1), 10);
}
```

{% endcode %}

{% code title="This does check the emitting address." fullWidth="true" %}

```solidity
event Transfer(address indexed from, address indexed to, uint256 amount);

function testERC20EmitsTransfer() public {
    // We check that the token is the event emitter by passing the address.
    vm.expectEmit(address(myToken));
    emit MyToken.Transfer(address(this), address(1), 10);

    // We perform the call.
    myToken.transfer(address(1), 10);
}
```

{% endcode %}

{% code title="We can also assert that multiple events are emitted in a single call." fullWidth="true" %}

```solidity
function testERC20EmitsBatchTransfer() public {
    // We declare multiple expected transfer events
    for (uint256 i = 0; i < users.length; i++) {
        // Here we use the longer signature for demonstration purposes. This call checks
        // topic0 (always checked), topic1 (true), topic2 (true), NOT topic3 (false), and data (true).
        vm.expectEmit(true, true, false, true);
        emit Transfer(address(this), users[i], 10);
    }

    // We also expect a custom `BatchTransfer(uint256 numberOfTransfers)` event.
    vm.expectEmit(false, false, false, true);
    emit BatchTransfer(users.length);

    // We perform the call.
    myToken.batchTransfer(users, 10);
}
```

{% endcode %}

{% code title="This example fails, as the expected event is not emitted on the next call." fullWidth="true" %}

```solidity
event Transfer(address indexed from, address indexed to, uint256 amount);

function testERC20EmitsTransfer() public {
    // We check that the token is the event emitter by passing the address as the fifth argument.
    vm.expectEmit(true, true, false, true, address(myToken));
    emit MyToken.Transfer(address(this), address(1), 10);

    // We perform an unrelated call that won't emit the intended event,
    // making the cheatcode fail.
    myToken.approve(address(this), 1e18);
    // We perform the call, but it will have no effect as the cheatcode has already failed.
    myToken.transfer(address(1), 10);
}
```

{% endcode %}

## envUint

Read an environment variable as `uint256` or `uint256[]`.

```solidity
vm.envUint("PRIVATE_KEY")
```

## load

Read a storage value directly.

```solidity
vm.load(targetContractAddress, bytes32(uint256(1)));
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.eridian.xyz/ethereum-dev/foundry-notes/tests/cheatcodes.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
