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

# Pay a list of recipients with a cap

> One Base transaction that pays the same USDC amount to each address in a list until a cap on the total is reached, and returns the total paid.

The program pays `amount` of USDC from the Pot to each address in `recipients`, in order, and stops before the payment that would take the total past `limit`. It returns the total the recipients received, and reverts when a recipient selected for payment is the zero address, the Pot runs short before the next payment, or a recipient receives a different amount.

**Target chains:** Base. The recorded simulation uses a Base fork.

## Prerequisites

Install the [Sauce CLI](https://docs.eco.com/sauce-sdk/installation.md) to compile and simulate. To send the transaction, configure a wallet with funds for gas and the Kitchen fee. Provide the required tokens in your Pot once it is deployed, or through `--fund`; see [funding](https://docs.eco.com/sauce-sdk/cli/funding.md).

## Program

`pot` is the Pot the program runs on, available without declaring it ([Names](https://docs.eco.com/sauce/names.md#balances)).

```ts pay-list.sauce.ts theme={null}
// Pays `amount` of USDC from the Pot to each of `recipients` in order, and stops paying once the
// next payment would take the total past `limit`. Each payment is measured at its recipient, and
// the program returns the total they received. The cook reverts, and nothing moves, when
// `recipients` is empty, `amount` is zero, a recipient selected for payment is the zero address,
// the Pot holds less than the next payment, or a recipient receives a different amount.
//
//   sauce simulate pay-list.sauce.ts --chain base --owner <address> \
//     --assume-balance USDC:<limit>n --args '["<recipient>","<recipient>"]' <amount> <limit>
//   sauce run pay-list.sauce.ts --chain base --wallet <name> \
//     --args '["<recipient>","<recipient>"]' <amount> <limit>
//
//   recipients: Address[]   who is paid, in order, as a JSON array of addresses
//   amount: Uint256         what each recipient gets, in USDC's base units (6 decimals): 1000000
//                           is 1 USDC
//   limit: Uint256          the most the program pays in all, in the same units
//
// On Base, 1 USDC each to three recipients with a cap of 2.5 USDC (the first two are paid):
//
//   sauce run pay-list.sauce.ts --chain base --wallet me --args \
//     '["<recipient1>","<recipient2>","<recipient3>"]' 1000000 2500000
function main(recipients: Address[], amount: Uint256, limit: Uint256): Uint256 {
  require(recipients.length > 0, "no recipients");
  require(amount > 0, "amount is zero");

  let total = 0;
  for (const to of recipients) {
    if (total + amount > limit) {
      break;
    }
    require(to != 0, "a recipient is the zero address");
    require(USDC.balanceOf(pot) >= amount, "not enough USDC in the Pot");
    const before = USDC.balanceOf(to);
    USDC.transfer(to, amount);
    const received = USDC.balanceOf(to) - before;
    require(received == amount, "a recipient received a different amount");
    total += received;
  }
  return total;
}
```

## How it works

* `recipients` is an `Address[]` parameter, so the list is a run-time argument passed as JSON in `--args`; the same bytecode pays any list.
* The cap is checked before each payment (`total + amount > limit`), so the loop ends with `break` and later recipients are not paid. The cook still succeeds.
* The Pot's balance is checked inside the loop, before each transfer, so a Pot that covers only some payments reverts the whole cook rather than paying a prefix of the list.
* `main` returns `Uint256`, the sum of the measured payments, so `sauce simulate` prints it as `main returns Uint256: ...`.

## Run the example

**1. Compile**

```bash theme={null}
sauce compile pay-list.sauce.ts --chain base
```

**2. Simulate**

```bash theme={null}
sauce simulate pay-list.sauce.ts --chain base --owner <your-address> \
  --assume-balance USDC:5 \
  --args '["<recipient>","<recipient>","<recipient>"]' 1000000 2500000
```

`--assume-balance USDC:5` gives the Pot 5 USDC for this simulation only. With a cap of 2.5 USDC and 1 USDC each, two of the three recipients are paid.

**3. Send**

```bash theme={null}
sauce run pay-list.sauce.ts --chain base --wallet <name> --fund USDC:2 \
  --args '["<recipient>","<recipient>","<recipient>"]' 1000000 2500000
```

`sauce tx` prints the unsigned transaction instead, for your own signer:

```bash theme={null}
sauce tx pay-list.sauce.ts --chain base --owner <your-address> --fund USDC:2 \
  --args '["<recipient>","<recipient>","<recipient>"]' 1000000 2500000
```

## Simulation result

Simulated on a local fork of Base at block 52965104 with the current contracts, with the command above, for `0x7099…79C8`, `0x3C44…93BC` and `0x90F7…b906`. Nothing was signed or sent.

```text theme={null}
The cook succeeds from 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266: gas used 190797 for the cook, after the Pot's deploy (1. below), returns 0x00000000000000000000000000000000000000000000000000000000001e8480
main returns Uint256: 2000000
Left in the Pot, not in the owner's wallet:
  3 USDC (it held 5 USDC before)
...
  2. the cook, from the owner 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266, gas used 190797
Assumed for this simulation only, by state override:
  the Pot holds 5 USDC: --assume-balance (its balance word 0xcb5320fe60abad81834e0e994e8a7a8eb33991917b05a5c0498fe1c0373a2087: Solidity mapping at slot 9)
What moved, in order:
...
  [3] Pot                -> 0x7099…79C8          1 USDC
  [4] Pot                -> 0x3C44…93BC          1 USDC
Net balance changes:
  0xDcFCc75A3C9a0EC798CAf81B6C84D4c5d5988c49 (the Pot): -2 USDC
  0x70997970C51812dc3A010C7d01b50e0d17dc79C8: +1 USDC
  0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC: +1 USDC
  0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (owner): -0.00000374478538635 ETH
```

The third payment would have taken the total to 3 USDC, past the 2.5 USDC cap, so the loop stopped after two and returned `2000000`. 3 of the 5 assumed USDC stayed in the Pot.

## Next steps

* [Pay USDC from the Pot](https://docs.eco.com/quickstarts/sauce/pay.md): one recipient, with the same measurement
* [Payroll by weight](https://docs.eco.com/quickstarts/sauce/payroll-by-weight.md): different amounts per recipient, from one budget
* [`sauce simulate`](https://docs.eco.com/sauce-sdk/cli/simulate), [Builtins](https://docs.eco.com/sauce/builtins.md)


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