> ## Documentation Index
> Fetch the complete documentation index at: https://phylaxsystems-docs-project-incidents.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Cheatcodes API Reference

> Complete API reference for cheatcodes in the Phylax Credible Layer

<Note>
  New to cheatcodes? Start with [What are Cheatcodes?](/credible/cheatcodes-overview) to understand what they are and why they exist.
</Note>

## State Management

### `forkPreTx`

Updates the active fork to the state prior to the assertion triggering transaction. Useful for:

* Checking chain state before a transaction
* Comparing values between pre and post states

```solidity theme={null}
function forkPreTx() external
```

### `forkPostTx`

Updates the active fork to the state after the assertion triggering transaction. Useful for:

* Verifying chain state after a transaction
* Comparing values between pre and post states

```solidity theme={null}
function forkPostTx() external
```

### `forkPreCall`

Updates the active fork to the state at the start of call execution for the specified id. `getCallInputs(..)` can be used to get ids to fork to.

```solidity theme={null}
function forkPreCall(uint256 id) external
```

### `forkPostCall`

Updates the active fork to the state after the call execution for the specified id. `getCallInputs(..)` can be used to get ids to fork to.

```solidity theme={null}
function forkPostCall(uint256 id) external
```

## Storage Operations

### `load`

Loads a storage slot from an address.

<Note>
  Using `forge inspect <ContractName> storage-layout` is an easy way to get the storage layout of a contract. This can be used to determine the storage slot of a specific variable to use in the cheatcode.
</Note>

```solidity theme={null}
function load(
    address target,
    bytes32 slot
) external view returns (bytes32 data)
```

You can see an example of how to use this cheatcode in the [Storage Lookups](/credible/use-case-mappings/storage-lookups) use case mapping.

## Transaction Data

### `getLogs`

Retrieves logs from the assertion triggering transaction.

```solidity theme={null}
struct Log {
    bytes32[] topics;   // Log topics, including signature
    bytes data;         // Raw log data
    address emitter;    // Log emitter address
}

function getLogs() external returns (Log[] memory logs)
```

You can see an example of how to use this cheatcode in the [Read Logs](/credible/use-case-mappings/read-logs) use case mapping.

### `getAllCallInputs`

Gets all call inputs for a given target and selector. This includes all types of calls (CALL, STATICCALL, DELEGATECALL, CALLCODE).

```solidity theme={null}
struct CallInputs {
    bytes input;                // Call data
    uint64 gas_limit;           // Gas limit
    address bytecode_address;   // Code execution address
    address target_address;     // Storage modification target
    address caller;             // Transaction caller
    uint256 value;              // Call value
    uint256 id;                 // Call id (used for forkPreCall and forkPostCall)
}

function getAllCallInputs(
    address target,
    bytes4 selector
) external view returns (CallInputs[] memory calls);
```

### `getCallInputs`

Gets call inputs for a given target and selector. Only includes calls made using 'CALL' opcode.

```solidity theme={null}
function getCallInputs(
    address target,
    bytes4 selector
) external view returns (CallInputs[] memory calls);
```

You can see an example of how to use this cheatcode in the [Function Call Inputs](/credible/use-case-mappings/function-call-inputs) use case mapping.

### `getStaticCallInputs`

Gets static call inputs for a given target and selector. Only includes calls made using 'STATICCALL' opcode.

```solidity theme={null}
function getStaticCallInputs(
    address target,
    bytes4 selector
) external view returns (CallInputs[] memory calls);
```

### `getDelegateCallInputs`

Gets delegate call inputs for a given target and selector. Only includes calls made using 'DELEGATECALL' opcode.

```solidity theme={null}
function getDelegateCallInputs(
    address target,
    bytes4 selector
) external view returns (CallInputs[] memory calls);
```

### `getCallCodeInputs`

Gets call code inputs for a given target and selector. Only includes calls made using 'CALLCODE' opcode.

```solidity theme={null}
function getCallCodeInputs(
    address target,
    bytes4 selector
) external view returns (CallInputs[] memory calls);
```

### Avoiding Double-Counting with Call Inputs

The specific call input cheatcodes (`getCallInputs`, `getStaticCallInputs`, `getDelegateCallInputs`, `getCallCodeInputs`) eliminate double-counting issues by allowing you to target only the specific call type you need. Use these instead of `getAllCallInputs()` when you want to avoid duplicate entries from proxy contracts.

For example, if you're monitoring a proxy contract and only want the actual delegate calls (not the proxy calls), use `getDelegateCallInputs()` instead of `getAllCallInputs()`.

```solidity theme={null}
// GOOD: Only get delegate calls, no duplicates
CallInputs[] memory delegateCalls = ph.getDelegateCallInputs(target, selector);

// AVOID: May include both proxy and delegate calls for the same operation
CallInputs[] memory allCalls = ph.getAllCallInputs(target, selector);
```

If you must use `getAllCallInputs()`, you may still need to filter out proxy calls:

```solidity theme={null}
// Filter proxy calls when using getAllCallInputs
for (uint256 i = 0; i < callInputs.length; i++) {
  if (callInputs[i].bytecode_address == callInputs[i].target_address) {
    continue; // Skip proxy calls, only process delegate calls
  }
  // Process the actual call
}
```

<Info>
  Internal calls are not actual EVM calls but rather a Solidity language feature. They are not traced by the CallTracer and will not result in `CallInputs` or trigger call-based assertions. However, using the `this` keyword (e.g., `this.functionName()`) creates an external call that will be traced and can trigger assertions.

  Example:

  ```solidity theme={null}
  function foo() external {
      // Internal call - not traced, no CallInputs generated
      bar();

      // External call via 'this' - traced, generates CallInputs
      this.bar();
  }

  function bar() public {
      // Function implementation
  }
  ```
</Info>

## State Change Tracking

### `getStateChanges`

Returns state changes for a contract's storage slot within the current call stack.

<Note>
  Using `forge inspect <ContractName> storage-layout` is an easy way to get the storage layout of a contract. This can be used to determine the storage slot of a specific variable to use in the cheatcode.
</Note>

```solidity theme={null}
function getStateChanges(
    address contractAddress,
    bytes32 slot
) external view returns (bytes32[] memory stateChanges);
```

You can see an example of how to use this cheatcode in the [State Changes](/credible/use-case-mappings/state-changes) use case mapping.

<Note>
  The array returned includes the initial value of the slot as the first element, so the length of the array is either 0 or >= 2.
</Note>

### Helper Functions

The following helpers convert state changes to specific types. Each has three variants:

* Basic: Get changes for a single slot
* Mapping: Get changes using a mapping key
* Mapping with Offset: Get changes using a key and offset for complex storage

#### `getStateChangesUint`

Gets state changes for a storage slot as uint256 values.

```solidity theme={null}
// Basic
function getStateChangesUint(
    address target,
    bytes32 slot
) internal view returns (uint256[] memory)

// With mapping
function getStateChangesUint(
    address target,
    bytes32 slot,
    uint256 key
) internal view returns (uint256[] memory)

// With mapping and offset
function getStateChangesUint(
    address target,
    bytes32 slot,
    uint256 key,
    uint256 offset
) internal view returns (uint256[] memory)
```

Similar helper functions exist for:

* `getStateChangesAddress`: Convert to address values
* `getStateChangesBool`: Convert to boolean values
* `getStateChangesBytes32`: Get raw bytes32 values

Each of these functions follows the same pattern with basic, mapping, and mapping-with-offset variants.

## Triggers

Triggers determine when your assertion functions will be executed. You can register different types of triggers in your assertion's `triggers()` function.

<Note>
  Use triggers to ensure that assertions are only called when they are needed in order to save gas and resources. For example, instead of triggering an assertion on every call to a contract, you can trigger it only on specific function calls that are able to change the state of the specific value you are asserting on.
</Note>

### Call Triggers

Call triggers execute your assertion when specific contract calls occur.

```solidity theme={null}
// Trigger on any call to the contract
// Note: It is not recommended to use this trigger as it will trigger the assertion on every call to the contract
// This can be expensive and inefficient
function registerCallTrigger(
    bytes4 assertionFnSelector
) internal view

// Trigger on specific function calls
function registerCallTrigger(
    bytes4 assertionFnSelector,
    bytes4 triggerSelector
) internal view
```

Example:

```solidity theme={null}
function triggers() external view override {
    // Run assertion on ALL calls to the contract
    registerCallTrigger(this.checkAllCalls.selector);

    // Run assertion only on transfer calls
    registerCallTrigger(
        this.checkTransfer.selector,
        IERC20.transfer.selector
    );
}
```

### Storage Triggers

Storage triggers execute your assertion when contract storage changes.

<Note>
  Using `forge inspect <ContractName> storage-layout` is an easy way to get the storage layout of a contract. This can be used to determine the storage slot of a specific variable to use in the cheatcode.
</Note>

```solidity theme={null}
// Trigger on ANY storage slot change
// Note: It is not recommended to use this trigger as it will trigger the assertion on every storage slot change
// This can be expensive and inefficient
function registerStorageChangeTrigger(
    bytes4 assertionFnSelector
) internal view

// Trigger on changes to a specific storage slot
function registerStorageChangeTrigger(
    bytes4 assertionFnSelector,
    bytes32 slot
) internal view
```

Example:

```solidity theme={null}
function triggers() external view override {
    // Run assertion on ANY storage change
    registerStorageChangeTrigger(this.checkAllStorage.selector);

    // Run assertion when totalSupply slot changes
    registerStorageChangeTrigger(
        this.checkSupply.selector,
        TOTAL_SUPPLY_SLOT
    );
}
```

### Balance Triggers

Executes assertion on ETH balance changes.

```solidity theme={null}
function registerBalanceChangeTrigger(
    bytes4 assertionFnSelector
) internal view
```

### Combining Triggers

Triggers can be combined for comprehensive coverage:

```solidity theme={null}
function triggers() external view override {
    // Multiple triggers for one assertion
    registerStorageChangeTrigger(this.mainInvariant.selector);
    registerCallTrigger(this.mainInvariant.selector);

    // Different assertions for different events
    registerBalanceChangeTrigger(this.checkBalances.selector);
    registerCallTrigger(
        this.checkCalls.selector,
        IERC20.transfer.selector
    );
}
```

## Helpers

### `getAssertionAdopter`

Get assertion adopter contract address associated with the assertion triggering transaction.

```solidity theme={null}
function getAssertionAdopter() external view returns (address);
```

This cheatcode removes the need to define an assertion adopter contract in the assertion contract constructor.

The cheatcode is only available in the `triggers()` function and the assertion functions. It cannot be used in the constructor since assertion contracts have no state during deployment.

### `console.log`

Prints debug information to the console during testing with `pcl test`. Useful for debugging assertion logic and understanding transaction flow.

```solidity theme={null}
function console.log(string memory message) external;
```

Example:

```solidity theme={null}
import { console } from "credible-std/console.sol";

function assertionExample() external {
    ph.forkPreTx();
    uint256 preBalance = token.balanceOf(user);

    ph.forkPostTx();
    uint256 postBalance = token.balanceOf(user);

    console.log("Checking user balance assertion");

    require(postBalance >= preBalance, "Balance should not decrease");
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Full API Reference" icon="file-code" href="https://phylaxsystems.github.io/credible-std/index.html">
    Autogenerated API documentation for credible-std
  </Card>

  <Card title="Assertion Guide" icon="code" href="/credible/write-first-assertion">
    Learn how to write assertions using cheatcodes
  </Card>

  <Card title="Use Case Mappings" icon="map" href="/credible/use-case-mappings/intro-use-case-mapping">
    See practical examples of cheatcodes in action
  </Card>

  <Card title="Assertions Book" icon="book-open" href="/assertions-book/assertions-book-intro">
    Real-world assertion examples and implementations
  </Card>

  <Card title="Testing Assertions" icon="flask" href="/credible/testing-assertions">
    Test your assertions locally
  </Card>
</CardGroup>
