---
description: Stops state diff recording and returns all recorded state changes
---

## `stopAndReturnStateDiff`

### Signature

```solidity
enum AccountAccessKind {
    Call,
    DelegateCall,
    CallCode,
    StaticCall,
    Create,
    SelfDestruct,
    Resume,
    Balance,
    Extcodesize,
    Extcodehash,
    Extcodecopy
}

struct ChainInfo {
    uint256 forkId;
    uint256 chainId;
}

struct AccountAccess {
    ChainInfo chainInfo;
    AccountAccessKind kind;
    address account;
    address accessor;
    bool initialized;
    uint256 oldBalance;
    uint256 newBalance;
    bytes deployedCode;
    uint256 value;
    bytes data;
    bool reverted;
    StorageAccess[] storageAccesses;
    uint64 depth;
}

struct StorageAccess {
    address account;
    bytes32 slot;
    bool isWrite;
    bytes32 previousValue;
    bytes32 newValue;
    bool reverted;
}

function stopAndReturnStateDiff() external returns (AccountAccess[] memory accesses);
```

### Description

Retrieves state changes recorded after a call to [`startStateDiffRecording`](/reference/cheatcodes/start-state-diff-recording). This function consumes the recorded state diffs and disables state diff recording. Call `startStateDiffRecording` again to resume recording.

### Returns

Returns an array of `AccountAccess` records containing:

| Field            | Description                                                    |
|------------------|----------------------------------------------------------------|
| `chainInfo`      | The chain and fork where the access occurred                   |
| `kind`           | The type of account access (Call, Create, etc.)                |
| `account`        | The account that was accessed                                  |
| `accessor`       | The account that initiated the access                          |
| `initialized`    | Whether the account had code, nonce, or balance before access  |
| `oldBalance`     | The previous balance of the account                            |
| `newBalance`     | The new balance of the account                                 |
| `deployedCode`   | The deployed bytecode (for Create operations)                  |
| `value`          | The value passed with the access                               |
| `data`           | The input data (msg.data) for the call                         |
| `reverted`       | Whether this access reverted                                   |
| `storageAccesses`| Array of storage slot reads/writes during this access          |
| `depth`          | The call depth at which this access occurred                   |

### Examples

#### Recording a CREATE operation

```solidity [test/StateDiffCreate.t.sol]
contract Counter {
    uint256 public data;
    constructor(uint256 _data) payable { data = _data; }
}

function testStateDiffCreate() public {
    vm.startStateDiffRecording();
    Counter counter = new Counter{value: 1 ether}(100);
    Vm.AccountAccess[] memory records = vm.stopAndReturnStateDiff();

    assertEq(records.length, 1);
    assertEq(uint8(records[0].kind), uint8(Vm.AccountAccessKind.Create));
    assertEq(records[0].account, address(counter));
    assertEq(records[0].newBalance, 1 ether);
    
    // Storage access for setting data
    assertEq(records[0].storageAccesses[0].isWrite, true);
    assertEq(records[0].storageAccesses[0].newValue, bytes32(uint256(100)));
}
```

#### Recording resumed execution

```solidity [test/StateDiffResume.t.sol]
contract Foo {
    Bar b;
    uint256 public val;
    constructor(Bar _b) { b = _b; }
    function run() external {
        val = val + 1;
        b.run();
        val = val + 1; // Creates a Resume record
    }
}

function testStateDiffResume() public {
    Bar bar = new Bar();
    Foo foo = new Foo(bar);

    vm.startStateDiffRecording();
    foo.run();
    Vm.AccountAccess[] memory records = vm.stopAndReturnStateDiff();

    assertEq(records.length, 3);
    assertEq(uint8(records[0].kind), uint8(Vm.AccountAccessKind.Call));  // foo.run()
    assertEq(uint8(records[1].kind), uint8(Vm.AccountAccessKind.Call));  // bar.run()
    assertEq(uint8(records[2].kind), uint8(Vm.AccountAccessKind.Resume)); // foo resumes
}
```

### Gotchas

:::note
A `Resume` AccountAccess is created only if storage accesses occurred after a context was resumed from a sub-call.
:::

### Related Cheatcodes

- [`startStateDiffRecording`](/reference/cheatcodes/start-state-diff-recording) - Start recording state changes
