> ## Documentation Index
> Fetch the complete documentation index at: https://docs.eco.com/llms.txt
> Use this file to discover all available pages before exploring further.

# sauce simulate

> See what a cook would do on the chain's state before you sign anything. Run it before every cook you send.

`sauce simulate` compiles a program, builds its cook and simulates it from the Pot's owner against a chain's current state. It broadcasts no transaction.

## Synopsis

```bash theme={null}
sauce simulate <file | -> --chain <slug|id> (--owner <address> | --pot <address>) [options]
sauce simulate <file | -> --chain solana --owner <pubkey> [--account NAME=<value>]… [options]
```

## Description

`sauce simulate` compiles the file (a `.sauce.ts` program or an [actions document](https://docs.eco.com/sauce-sdk/cli/actions.md)), builds the [cook](https://docs.eco.com/sauce/cook.md) on the Pot of `--owner` (with `--salt`), or on the Pot `--pot` names, and simulates it as sent from the owner. It broadcasts nothing and starts no local node. Without a key it signs nothing; given the owner's key and `--fund`, it signs the token pulls and does not send them. On an EVM chain any address works as the owner.

It prints the gas, what `main` returns and what the cook moved, or the decoded reason it reverts.

**On an EVM chain** it simulates through `eth_simulateV1`, which returns the cook's logs. The report lists the ERC-20 transfers and approvals (registry symbols, whole units), the native transfers the node traces, and each address's net balance change. An endpoint without `eth_simulateV1` falls back to `eth_call` with state overrides: that route gives the result and the gas, but no logs. The report names the route it took.

* **A Pot not deployed yet** is deployed in the simulation first, from `--owner` (and `--salt`). Any account may send the Pot's deployment, and the Pot is the owner's either way.
* **The cook's value** defaults to the Kitchen's execution fee, read from the chain. An owner holding less than the value is given it for the simulation.
* **`--assume-balance TOKEN:amount`** gives the Pot that balance for this simulation only, by state override. The command finds the token's balance storage by asking the token, with `eth_call`. A token that stores no balance it reports (rebasing tokens, shares) is refused. [Funding a Pot](https://docs.eco.com/sauce-sdk/cli/funding.md#simulate-with-balances-the-pot-does-not-hold) covers the amount syntax.
* **`--fund`** with the owner's key (`--keystore`, `--private-key` or `--wallet`) includes the pulls `sauce run --fund` would make, signed and not sent; an approval the run would ask for is reported and simulated before the cook, not sent. With no key the pulls cannot be signed, so the Pot is credited what they would bring, by state override, and `--sweep` still runs.
* **`--block`** pins every read and the simulation to one block, so a price read at that block can be simulated on the same state.

**On Solana** it simulates the Kitchen's cook from `--owner`, with signatures unchecked, and prints the compute units, the execution fee it read, and each token account's and lamport balance change, or the reason and the program logs. Each account `main` takes is given with `--account`; the accounts the token methods and venue namespaces add are derived. Solana's `simulateTransaction` takes no account overrides, so the owner must hold the Pot's rent and the fees. A cook too large for one transaction, or one given `--assume-balance`, is simulated in a local copy of the accounts it names, with LiteSVM, which the package installs on first use ([`sauce runtime`](https://docs.eco.com/sauce-sdk/cli/runtime)). [Solana](https://docs.eco.com/sauce-sdk/cli/solana.md) covers the account forms and `--via engine`.

Simulation needs the release's engine deployed on the chain. It is not limited to the supported chains: it runs on a preview chain where the release is deployed, such as Optimism. Where the engine has no code, the command exits 1 with `the released engine <engine address> is not deployed on <chain>: this SDK's cook cannot run there`.

## Prerequisites

On an EVM chain, the release's engine must be deployed on the chain. `sauce pot --chain <chain> --owner <address>` reports whether it is.

## Options

| Option | Description |
| - | - |
| `--chain <slug\|id>` | The chain the program runs on (`base`, `8453`, `solana`) |
| `--target <evm\|svm>` | Checked against the chain. `svm` with no `--chain` means Solana |
| `--source-dir <dir>` | The directory the program's relative imports resolve from. Default: beside the file; for stdin, the current directory |
| `--owner <address>` | The Pot's owner, which derives the Pot with the salt (default salt 0) |
| `--salt <label>` | Name one of the owner's Pots: the salt is `keccak256(label)` |
| `--salt-hex <bytes32>` | Give the Pot's salt exactly |
| `--args-json <json\|file>` | `main`'s arguments as one JSON array, inline or in a file |
| `--rpc-url <url>` | Your own RPC endpoint for the chain. Default: a built-in public one |
| `--config <file>` | A file of your own endpoints: `{ "rpcUrls": { "<chain id>": "<url>" } }` |
| `--offline` | Read no chain: no endpoint, built-in ones included |
| `--assume-balance <TOKEN:amount>` | Give the Pot this balance, in whole tokens, for the simulation only: `USDC:2`, `ETH:0.1`. Repeatable |
| `--expect-revert <text>` | Expect the cook to revert with a reason containing this text: exit `0` only if it does |
| `--wallet <name>` | The owner's wallet: names the owner, and on EVM signs `--fund`'s pulls |
| `--wallets [<dir>]` | The wallet directory. Default: `~/.sauce/wallets` |
| `--password-env <NAME>` | Read the password from the environment variable `NAME`, the only variable read |
| `--password-file <path>` | Read the password from a file only you can read. Without a password source, it is asked for |
| `--password-command <command>` | Use what this command prints as the password, such as a secret manager's CLI |
| `--json` | Print one JSON object instead |
| `-h, --help` | Show the help |
| `--no-update-check` | Print no notice of a newer `sauce`, and read no registry for one |
| `--args <value>…` | `main`'s arguments in order: an integer as digits, a negative one too (`-5`), JSON for an array or a tuple. Put `--` before a word that starts like a flag |

### EVM chains only

| Option | Description |
| - | - |
| `--pot <address>` | The Pot itself, by address, instead of `--owner` |
| `--value <wei>` | The cook's value: the Kitchen fee plus native coin the program spends. Default: the fee, read from the chain |
| `--block <number\|tag>` | Simulate on this block: a number, or `latest`, `safe`, `finalized`. Default: `latest` |
| `--fund <TOKEN:amount>` | Pull tokens into the Pot in the cook: `USDC:1.5` (whole tokens), `ETH:0.01` |
| `--fund-mode <mode>` | `permit2` (default), `permit`, `allowance` or `transfer` |
| `--sweep` | Return what is left of each funded token afterwards |
| `--keystore <path>` | The owner's keystore: names the owner and signs `--fund`'s pulls |
| `--private-key <hex>` | Sign with a raw key instead. It lands in your shell history |

### Solana only

| Option | Description |
| - | - |
| `--account NAME=<address>` | An account `main` takes, by name: an address, `pot`, `owner`, `authority` (the account that signs the engine call: the Pot, or the owner with `--via engine`), `system` (the System Program), `pot:USDC` (the Pot's USDC account), `@to:USDC` (the USDC account of `main`'s argument `to`), `mint:USDC`, `program:USDC` (its token program), `slot:@pool:USDC.vaultA` (a pool's account) or `pda:<program>:<seeds>`. Accounts the token methods and venue namespaces add, and those a program derives where it uses them (`Account.pda(…)`), need no flag. A slot derived from the Pot, the owner or the authority takes only the account its derivation gives |
| `--accounts <json\|file>` | The accounts `main` takes as one JSON object of name to value, in `--account`'s forms, inline or in a file |
| `--via <kitchen\|engine>` | The Kitchen's cook on the Pot (default), or the engine's own cook, with no Pot |
| `--max-execution-fee <lamports>` | Refuse a cook whose execution fee is above this |
| `--lookup-table <address>` | An address lookup table holding the cook's accounts |
| `--keypair <path>` | The owner's keypair, which names the owner. Nothing is signed |

### Low-level options

`--help` lists these apart, with the note "a program's inputs are main's parameters, given with --args".

| Option | Description |
| - | - |
| `--define NAME=VALUE` | A compile-time value for a name the program leaves undeclared: an integer, `0x` hex, `true` or `false`; base58 on Solana |
| `--defines <file.json>` | Compile-time values from a JSON object of name to value. `--define` takes precedence |

## Output

The text report on an EVM chain, top down:

1. The headline: the cook succeeds, with its gas and what `main` returned (decoded where `main` declares a return type).
2. What is left in the Pot, with what it held before.
3. The route and block it simulated on, and each transaction simulated: the Pot's deployment first when needed, then the cook.
4. What the simulation assumed, by state override.
5. What moved, in order, each party by role: `wallet`, `Pot`, `Kitchen`, a registry name or a token symbol.
6. Each address's net balance change.

A cook that reverts exits `1`, and the first line is `The cook reverts: <reason>`. A `require` message decodes as `the program threw "…"`. With `--json`, `reverted: true` and `error` lead the object, and the same line leads stderr.

With `--json` a successful simulation prints one object. Its main fields:

| Field | Contents |
| - | - |
| `ok` | `true` when the cook succeeds |
| `chain`, `block`, `path` | The chain, the block simulated on, and the route (`eth_simulateV1` or the `eth_call` fallback) |
| `from`, `to`, `value` | The owner, the Pot and the cook's value in wei |
| `deployPot` | The deployment simulated first, when the Pot had no code |
| `assumed` | Each balance given by state override, with why |
| `gas`, `transactions` | The cook's gas, and each simulated transaction with its gas |
| `returns` | What `main` returned |
| `leftInPot`, `moves`, `transfers`, `approvals`, `nativeTransfers`, `balanceChanges`, `otherLogs` | What the cook moved and left, as the text report lists it |

Exit codes: `0` when the cook succeeds (with `--expect-revert`, when it reverts with the expected reason), `1` when it reverts (with `--expect-revert`, when it succeeds or reverts otherwise), `2` for a usage error.

## Examples

The examples simulate [`pay.sauce.ts`](https://docs.eco.com/sauce-sdk/cli/compile#compile-for-base) on Base. The owner `0x1111…1111` is an arbitrary address; its Pot has no code on Base, so each simulation deploys it first. The Kitchen's address is shown as `<kitchen address>`; it is on the [deployments](https://docs.eco.com/sauce-sdk/reference/deployments.md) page.

### Simulate with a balance the Pot does not hold

```bash theme={null}
sauce simulate pay.sauce.ts --chain base --owner 0x1111111111111111111111111111111111111111 \
  --assume-balance USDC:5 \
  --args 0x2222222222222222222222222222222222222222 1000000
```

```text theme={null}
The cook succeeds from 0x1111111111111111111111111111111111111111: gas used 88091 for the cook, after the Pot's deploy (1. below), returns 0x
Left in the Pot, not in the owner's wallet:
  4 USDC (it held 5 USDC before)
  Only another cook moves it out. To end in a wallet, the program must send it there, or name the wallet as the recipient of the call that produces it.
Simulated with eth_simulateV1 on the state of block <block>; nothing was signed or sent:
  1. Kitchen.deployPot(0x1111111111111111111111111111111111111111, 0x0000000000000000000000000000000000000000000000000000000000000000), gas used 667003: Pot 0x6c9175d272D49e6C8C139A3FE6BC6fDb422eD3Fe is not deployed on base yet, so the simulation deploys it first, as sauce run does (asking, or with --yes) and sauce tx plans. Any account may send it; the Pot is the owner's either way.
  2. the cook, from the owner 0x1111111111111111111111111111111111111111, gas used 88091
Assumed for this simulation only, by state override:
  the Pot holds 5 USDC: --assume-balance (its balance word 0x084287d900ad004325a89a942f9a718ace54e0752b69050660ae8cb441df9f1f: Solidity mapping at slot 9)
What moved, in order:
  [1] wallet 0x1111…1111 -> Pot 0x6c91…D3Fe      0.00000374478538635 ETH  the cook's value
  [2] Pot                -> Kitchen              0.00000374478538635 ETH  the Kitchen's fee
  [3] Pot                -> 0x2222…2222          1 USDC
Net balance changes:
  0x6c9175d272D49e6C8C139A3FE6BC6fDb422eD3Fe (the Pot): -1 USDC
  0x2222222222222222222222222222222222222222: +1 USDC
  0x1111111111111111111111111111111111111111 (owner): -0.00000374478538635 ETH
  <kitchen address> (Kitchen): +0.00000374478538635 ETH
```

The cook's value is the Kitchen's fee, which the Pot forwards to the Kitchen.

### Check that a guard fires

With 0.5 USDC in the Pot, the program's `require` stops a 1 USDC payment:

```bash theme={null}
sauce simulate pay.sauce.ts --chain base --owner 0x1111111111111111111111111111111111111111 \
  --assume-balance USDC:0.5 \
  --args 0x2222222222222222222222222222222222222222 1000000 --expect-revert "not enough USDC"
```

```text theme={null}
As expected, the cook reverts: the program threw "not enough USDC"
The cook reverts: the program threw "not enough USDC"
Simulated with eth_simulateV1 on the state of block <block>; nothing was signed or sent:
…
```

The command exits `0`. Without `--expect-revert`, the same simulation exits `1`.

### Print the report as JSON

```bash theme={null}
sauce simulate pay.sauce.ts --chain base --owner 0x1111111111111111111111111111111111111111 \
  --assume-balance USDC:5 --json \
  --args 0x2222222222222222222222222222222222222222 1000000
```

```json theme={null}
{
  "ok": true,
  "leftInPot": [
    {
      "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "symbol": "USDC",
      "decimals": 6,
      "amount": "4000000",
      "formatted": "4",
      "before": "5000000"
    }
  ],
  "chain": "base",
  "block": "<block>",
  "from": "0x1111111111111111111111111111111111111111",
  "to": "0x6c9175d272D49e6C8C139A3FE6BC6fDb422eD3Fe",
  "value": "3744785386350",
  "path": "eth_simulateV1",
  "deployPot": {
    "kitchen": "<kitchen address>",
    "owner": "0x1111111111111111111111111111111111111111",
    "salt": "0x0000000000000000000000000000000000000000000000000000000000000000"
  },
  "gas": "88091",
  "gasKind": "used",
  "returns": "0x",
  "transfers": [
    {
      "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "symbol": "USDC",
      "decimals": 6,
      "kind": "transfer",
      "from": "0x6c9175d272D49e6C8C139A3FE6BC6fDb422eD3Fe",
      "to": "0x2222222222222222222222222222222222222222",
      "amount": "1000000",
      "formatted": "1"
    }
  ],
  "approvals": []
}
```

The output is trimmed: `assumed`, `transactions`, `moves`, `nativeTransfers`, `balanceChanges` and `otherLogs` are left out.

### Simulate a funded run with no key

```bash theme={null}
sauce simulate pay.sauce.ts --chain base --owner 0x1111111111111111111111111111111111111111 \
  --fund USDC:1.5 --sweep \
  --args 0x2222222222222222222222222222222222222222 1000000
```

```text theme={null}
--fund without a key: pulling USDC needs the owner's signature (--keystore or --private-key), so the pulls are not simulated; the Pot is credited what they would bring, for this simulation only
The cook succeeds from 0x1111111111111111111111111111111111111111: gas used 105777 for the cook, after the Pot's deploy (1. below), returns 0x
…
What moved, in order:
  [1] wallet 0x1111…1111 -> Pot 0x6c91…D3Fe      0.00000374478538635 ETH  the cook's value
  [2] Pot                -> Kitchen              0.00000374478538635 ETH  the Kitchen's fee
  [3] Pot                -> 0x2222…2222          1 USDC
  [4] Pot                -> wallet               0.5 USDC
```

`--sweep` returned the 0.5 USDC the program left in the Pot.

## Next steps

* [`sauce run`](https://docs.eco.com/sauce-sdk/cli/run): sign and send the cook after simulating it.
* [`sauce tx`](https://docs.eco.com/sauce-sdk/cli/tx): the unsigned cook, for another signer.
* [Funding a Pot](https://docs.eco.com/sauce-sdk/cli/funding.md): `--fund`, `--fund-mode`, `--sweep` and `--assume-balance`.
* [Solana](https://docs.eco.com/sauce-sdk/cli/solana.md): accounts, `--via` and the local copy.
* [Chains and endpoints](https://docs.eco.com/sauce-sdk/cli/chains-and-endpoints.md): endpoints and preview chains.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.