> ## 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.

# Settle: sweep a Pot to one recipient

> The settle program shipped in @eco-incorp/sauce: sweep the Pot's balance of a list of tokens to one recipient with a minimum-output floor on the first token. EVM source and the generated SVM twin, with the package's own design notes.

`settle.sauce.ts` is a standalone, reusable program that ships in `@eco-incorp/sauce` and is exported as `settleSource()` from `/recipes` and as the raw file at `@eco-incorp/sauce/recipes/settle.sauce.ts`. It sweeps the Pot's current balance of every listed token to one recipient, enforcing a minimum-output floor on `tokens[0]` before anything moves. The three values arrive as ABI-encoded runtime entry arguments appended after the program, so one compiled blob serves every token list, floor and recipient, which is what lets the `/verify` surface pin a single program hash.

## Prerequisites

Complete [Sauce setup](/programmable-transactions/sauce/getting-started) and use the documented SDK and compiler versions. For execution, confirm the target deployment, Pot ownership, balances and Kitchen fee. Simulate the complete transaction and estimate its gas before submitting it.

Save [IERC20.json](/cookbook/sauce/abis/IERC20.json) in an `artifacts` directory beside the source. Supply a nonempty `tokens` array; the program reads `tokens[0]` even when `minOut` is zero.

## EVM program

```typescript settle.sauce.ts theme={null}
import { IERC20 } from "./artifacts/IERC20.json";

function main(tokens: Address[], minOut: Uint256, recipient: Address): Uint256 {
  const floorToken = IERC20.at(tokens[0]);
  const floorBal: Uint256 = floorToken.balanceOf(ctx.self());
  if (minOut > 0) {
    if (floorBal < minOut) {
      throw "settle: balance below minOut";
    }
  }
  for (let i = 0; i < tokens.length; i = i + 1) {
    const t = IERC20.at(tokens[i]);
    const bal: Uint256 = t.balanceOf(ctx.self());
    if (bal > 0) {
      t.transfer(recipient, bal);
    }
  }
  return floorBal;
}
```

The shipped file carries an extended header comment. The points it makes:

* **Composing after another program.** A `V12Pot.cook` runs exactly one program, so "do the thing, then sweep" is two top-level `cook()` calls joined by an owner-authorised multicall in one transaction. The multicall contract must be the Pot's `owner` and must propagate a reverting call's revert data. It must never be a permissionless batcher: owning the batcher is owning the Pot.
* **The compiled program is a function of the file and the compiler pin only**, never of the arguments. Keep `tokens`, `minOut` and `recipient` as parameters; moving any of them to a compile-time `define` would fold it into the program and break the pinned-hash design.
* **`tokens[0]` is the floor token by position.** `minOut` is enforced against its balance before any transfer runs, and it is swept first with no external call between the check and the transfer, so the amount checked is the amount transferred.
* **Known and accepted property.** The floor and the sweep read the Pot's current balance, not a delta against a baseline; a pre-existing balance counts toward `minOut` and rides to the recipient. The Pot ending clean is the point.

## SVM twin

The SVM version is generated by `svmSettleSource(escrowCount)` exported from `@eco-incorp/sauce/svm` rather than hand-written: on Solana a token account must be attached to the instruction and addressed by a literal account index, so the escrow count is a compile-time property and the sweeps are unrolled. `SETTLE_MIN_OUT` and `SETTLE_SPL_COUNT` arrive as compile-time `defines`. Balances are read from the escrow account's data and moved with an SPL Token `TransferChecked` CPI, which works for classic SPL and Token-2022 mints; transfer-hook mints are out of scope.

```typescript settle.svm.sauce.ts theme={null}
const SETTLE_MIN_OUT = 0n;
const SETTLE_SPL_COUNT = 0n;

function main(tokenProgram0: Account, tokenProgram1: Account, escrow0: Account<Writable>, mint0: Account, dest0: Account<Writable>, owner: Account<Signer>): Uint256 {
  const floorBal = svm.sload(escrow0, 64, 8).toLe();
  if (SETTLE_MIN_OUT > 0) {
    if (floorBal < SETTLE_MIN_OUT) {
      throw "settle: balance below minOut";
    }
  }

  // escrow 0: read balance then decimals, then TransferChecked the whole balance to this
  // recipient's ATA, via this escrow's token program (tokenProgram0 for the first
  // `SETTLE_SPL_COUNT` escrows, tokenProgram1 for the rest).
  const bal0 = svm.sload(escrow0, 64, 8).toLe();
  const dec0 = svm.sload(mint0, 44, 1).toLe();
  if (bal0 > 0) {
    const tp0 = 0 < SETTLE_SPL_COUNT ? tokenProgram0 : tokenProgram1;
    const tag0 = hex`0c`;                                   // TransferChecked
    const data0 = tag0.concat(bal0.toBytesLe(8)).concat(dec0.toBytesLe(1));
    svm.call(tp0, [escrow0, mint0, dest0, owner], data0);
  }

  return floorBal;
}
```

Partner verification: recompile `svmSettleSource(n)` with the options in the package and byte-compare against what you were handed. There is no golden hash for the SVM program.

## Troubleshooting

A minimum-output failure compares `minOut` with the Pot's entire balance of `tokens[0]`, including any existing funds. Check token ordering and smallest-unit amounts. For Solana, check each escrow, mint, destination and authority against the generated manifest.

## Next steps

[`settleSource`](/sdk-reference/sauce/recipes/settle#settlesource), [`SETTLE_SOURCE_PATH`](/sdk-reference/sauce/recipes/settle#settle-source-path), [`SAUCE_BASE_DIRS`](/sdk-reference/sauce/recipes/settle#sauce-base-dirs), and the [svm](/sdk-reference/sauce/svm/client) subpath.
