Who may call it
A private Pot accepts a directcook call only from its owner. A direct call from another account reverts with NotOwner(). A Shared Pot, which has no owner, accepts a cook from anyone.
A Pot created by the current Kitchen has a second entry point, cookSigned: the owner signs a cook as EIP-712 typed data, and any account submits it and pays the gas (Signed cooks).
The sauce command builds the cook for the owner: sauce simulate runs it without a key, sauce run signs and sends it with the owner’s wallet, and sauce tx prints it unsigned for another signer. sauce sign signs a cook for another account to submit with cookSigned.
What the Pot does
- It checks that the sender is its owner, and reverts with
NotOwner()otherwise. ForcookSignedit checks the owner’s signature, the nonce, the deadline and the submitter instead (Signed cooks). - It forwards the Kitchen’s fee to the Kitchen. For
cook, the fee comes out of the cook’s value: a value below the fee reverts withFeeNotPaid(uint256 required, uint256 provided). ForcookSigned, it comes out of the Pot’s own balance, which includes the value sent, up to the signedmaxExecutionFee: a fee above the smaller of the two reverts withFeeNotPaid. - It runs the program on
engine, inside itself and on its own balances. The program runs as the Pot:potandctx.self()are the Pot, and every call the program makes comes from the Pot. - It returns what
mainreturns.
pay.sauce.ts
The unsigned cook
sauce tx prints the cook as JSON for any wallet to sign. When the Pot has no code yet it prints a plan, the Pot’s deployment first:
sendCalls, both transactions as one batch for a wallet that sends batches).
datais0xb38dbf14, the selector ofcook(address,bytes), followed by the ABI encoding of the engine’s address andprogram. Hereprogramis 287 bytes: the 223-byte program and two 32-byte arguments.valueis 3,744,785,386,350 wei, the Kitchen’s fee read when the cook was built. The program spends no ETH, so nothing is added.- Once the Pot has code,
sauce txprints the cook alone:chainId,to,dataandvalue. --format castprints each transaction as acast sendline instead.
Atomicity
The program’s steps run in order inside the cook. An uncaught failure, such as a failedrequire, a call that reverts or a checked arithmetic error, reverts the whole cook, the Kitchen’s fee with it: nothing moves, and the sender pays only the gas used up to the failure. Simulated on a local fork of Base at block 52965000 with the current contracts, with no USDC in the Pot, the same cook gives:
try/catch block narrows the rollback: when the block fails, its own calls, writes and assignments roll back, the handler runs, and the cook goes on; work before the block remains. Solana has no catch, so there every failure reverts the cook.
The rollback covers this transaction only. What earlier transactions did stays done: an approval a previous cook gave outlives that cook, and its spender can still use it after a later cook reverts. Approve exactly what the next call spends.
Return values
Whatmain returns is the cook’s return data. The ABI declares returns (bytes), but the bytes are the value itself, laid out by the type main declares, with no ABI bytes wrapper around them:
An array is therefore not what an ABI decoder reads. To return ABI-encoded data, return
abi.encode(...) as bytes. Solana has no abi.encode.
balance.sauce.ts
sauce simulate decodes the return data as the declared type. With 5 USDC assumed in the Pot, on a local fork of Base at block 53122782 with the current contracts:
Gas
On an EVM chain the wallet that sends the cook pays its gas in the chain’s native coin. A cook’s gas is the transaction’s, the Pot’s and the Kitchen’s, plus the program’s own, which the engine runs step by step. Measured through the released engine and a Pot the Kitchen made, on a local chain:
The programs on these pages, simulated on a local fork of Base at block 52965000 with the current contracts:
- The figure for your program is the simulation’s, on the chain as it is when you run it. A swap that crosses more of a pool’s price range than it did in the simulation spends more, so leave room between the simulated gas and the gas limit.
- On Base and other OP Stack chains each transaction also pays a fee for publishing its data to Ethereum.
sauce runcounts it in what a run cost. - A cook that fails pays the gas it used up to the failure, and no Kitchen fee.
On Arc
Arc’s native coin is USDC, so a cook’s value, the Kitchen’s fee within it, and its gas are paid in USDC. As native value USDC has 18 decimals; it is the same balance as the 6-decimalUSDC token. Simulated on a local fork of Arc at block 27376858 with the current contracts, checked.sauce.ts with --args 7 5:
maxFeePerGas (or gasPrice) of at least 20 gwei, its minimum base fee.
On Solana
A cook on Solana is an instruction, and there are two ways to send one:
Both carry a signed
max_execution_fee, and a fee above it refuses the cook before anything runs. The same compiled program runs either way, with the same account indices.
- Compute. A transaction has a budget of 1,400,000 compute units, shared by the engine and every program it calls. A cook that runs out fails whole.
pay.sauce.tsused 49,931 compute units in the simulation below. - Heap. Every cook requests a 256 KiB heap frame, and a program has 64 KiB of working memory per run. The
saucecommand and the SDK’s client add the request; a cook assembled by hand must carry it once. - Signature fees. Each signature costs 5,000 lamports. In the simulation below the owner paid 90,672 lamports for the cook: the Kitchen’s 85,672 and one signature.
- Size. A cook too large for one transaction is staged first (Bytecode).
sauce txthen prints a plan of steps: the setup, the cook, then closing the code buffer.
sauce command’s local copy (LiteSVM) of Solana at slot 460261665, with the current engine and Kitchen and 5 USDC assumed in a Pot not created yet (abridged):
Next steps
sauce simulate,sauce txandsauce run: every flag of the commands that build a cook.- Pot: where the program runs and where its results end.
- Security considerations: what to check before you sign a cook.
