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

# Keep a USDC reserve in the Pot and supply the rest to Aave

> One Ethereum or Base transaction that supplies the Pot's USDC above a reserve to Aave V3, or withdraws a shortfall back into the Pot.

This program keeps a target USDC reserve in the Pot. It supplies excess USDC to Aave V3 or withdraws from the Pot's Aave position to cover a shortfall. It skips movements smaller than `minMove`.

The program checks the supplied token address, verifies the balance after a supply and checks the amount withdrawn. An unhandled failure from Aave reverts the cook.

**Target chains:** Base and Ethereum. Both registries include `USDC` and `AaveV3.Pool`; 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 USDC for the program and native coin for gas and the Kitchen fee.

## Program

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

```ts supply-idle.sauce.ts theme={null}
// Keeps `reserve` USDC liquid in the Pot and the rest supplied to Aave V3, credited to the Pot.
// When the Pot holds `reserve` plus at least `minMove`, it supplies the excess. When it holds less
// than `reserve`, it withdraws the shortfall from its supplied USDC, as much as is there. A move
// under `minMove` is skipped. The cook reverts if `aToken` is zero or Aave refuses the move.
//
//   sauce simulate supply-idle.sauce.ts --chain <chain> --owner <address> \
//     --assume-balance USDC:<whole-tokens> --args <reserve> <minMove> <aToken>
//   sauce run supply-idle.sauce.ts --chain <chain> --wallet <name> \
//     --fund USDC:<whole-tokens> --args <reserve> <minMove> <aToken>
//
//   reserve: Uint256   the USDC to keep liquid in the Pot, in USDC's base units (6 decimals):
//                      500000000 is 500 USDC
//   minMove: Uint256   the smallest supply or withdrawal to make, in the same units:
//                      50000000 is 50 USDC
//   aToken: Address    Aave's aUSDC token on the chain. The registry declares no aToken lookup
//                      on AaveV3.Pool, so the Pot's supplied balance is read from this input.
//
// On Base, keep 500 USDC liquid and move nothing under 50:
//
//   sauce run supply-idle.sauce.ts --chain base --wallet me --fund USDC:1000 \
//     --args 500000000 50000000 0x4e65fE4DbA92790696d040ac24Aa414708F5c0AB

function main(
  reserve: Uint256,
  minMove: Uint256,
  aToken: Address,
): { supplied: Uint256; withdrawn: Uint256; liquid: Uint256; deposited: Uint256 } {
  require(aToken != 0, "aToken is zero");

  const liquid = pot.USDC;
  const deposited = Token(aToken).balanceOf(pot);

  let supplied: Uint256 = 0;
  let withdrawn: Uint256 = 0;
  if (liquid > reserve && liquid - reserve >= minMove) {
    // Supply the excess for the Pot, so a later run can withdraw it.
    supplied = liquid - reserve;
    USDC.approve(AaveV3.Pool, supplied);
    AaveV3.Pool.supply(USDC, supplied, pot, 0);
    require(pot.USDC == liquid - supplied, "supply did not take the whole excess");
  } else if (liquid < reserve) {
    // Withdraw the shortfall, or all that is supplied if that is less.
    const shortfall = reserve - liquid;
    const wanted = shortfall < deposited ? shortfall : deposited;
    if (wanted > 0 && wanted >= minMove) {
      AaveV3.Pool.withdraw(USDC, wanted, pot);
      withdrawn = pot.USDC - liquid;
      require(withdrawn >= wanted, "withdraw returned less than asked");
    }
  }

  return {
    supplied,
    withdrawn,
    liquid: pot.USDC,
    deposited: Token(aToken).balanceOf(pot),
  };
}
```

## How it works

* The registry's `AaveV3.Pool` declares no lookup of a reserve's aToken (`sauce globals --chain base --protocol AaveV3` lists the methods it declares). The program therefore takes the aUSDC address as the `aToken` parameter and reads the Pot's supplied USDC as `Token(aToken).balanceOf(pot)`.
* `supply` names `pot` as `onBehalfOf`, so the aUSDC is minted to the Pot. A later run of the same program withdraws from that balance; aUSDC credited to a wallet could not be withdrawn by a cook.
* `withdraw`'s result is discarded, and a discarded result is neither decoded nor checked. `withdrawn` is therefore the change in the Pot's USDC, and the program requires it to be at least the amount asked.

## Run the example

**1. Compile**

```bash theme={null}
sauce compile supply-idle.sauce.ts --chain base
sauce compile supply-idle.sauce.ts --chain ethereum
```

**2. Simulate**

```bash theme={null}
sauce simulate supply-idle.sauce.ts --chain base --owner <your-address> \
  --assume-balance USDC:1000 --args 500000000 50000000 <aToken>
```

`--assume-balance USDC:1000` gives the Pot 1,000 USDC for this simulation only, 500 above a `reserve` of 500 USDC, so the program takes the supply branch. `<aToken>` is Aave's aUSDC on the chain: on Base, the aBasUSDC address in the program's header.

**3. Send**

```bash theme={null}
sauce run supply-idle.sauce.ts --chain base --wallet <name> \
  --fund USDC:1000 --args 500000000 50000000 <aToken>
```

`--fund USDC:1000` pulls 1,000 USDC from your wallet into the Pot in the same cook. `sauce tx` prints the unsigned transactions instead, for your own signer: the Pot's deployment if it has no code yet, the transfer of the USDC into the Pot, then the cook.

```bash theme={null}
sauce tx supply-idle.sauce.ts --chain base --owner <your-address> \
  --fund USDC:1000 --args 500000000 50000000 <aToken>
```

## Simulation result

Simulated on a local fork of Base at block 52965104 with the current contracts. The command is the one above, with aBasUSDC as `aToken`. Nothing was signed or sent.

```text theme={null}
main returns { supplied: Uint256, withdrawn: Uint256, liquid: Uint256, deposited: Uint256 }: { supplied: 500000000, withdrawn: 0, liquid: 500000000, deposited: 499999999 }
Left in the Pot, not in the owner's wallet:
  500 USDC (it held 1000 USDC before)
  499.999999 aBasUSDC
...
What moved, in order:
...
  [3] Pot                -> aBasUSDC 0x4e65…c0AB  500 USDC
  [4] mint               -> Pot                   499.999999 aBasUSDC
```

The Pot held 1,000 USDC against a 500 USDC reserve, so the program supplied the 500 USDC excess and kept 500 liquid. Aave minted 499.999999 aBasUSDC to the Pot, which `deposited` reports. The cook used 303,066 gas.

The withdrawal branch was not simulated: it needs aUSDC in the Pot, and `sauce simulate` refuses `--assume-balance` for aBasUSDC because the token computes its balance rather than storing it.

## Next steps

* [Repay by health factor](https://docs.eco.com/quickstarts/sauce/aave-repay-by-health.md): repays the Pot's Aave V3 USDC debt when its health factor is below a target.
* [Borrow with a health-factor floor](https://docs.eco.com/quickstarts/sauce/aave-borrow-guard.md): supplies WETH, borrows USDC and requires a minimum health factor in one cook.
* [`sauce simulate`](https://docs.eco.com/sauce-sdk/cli/simulate), [Names](https://docs.eco.com/sauce/names.md), [Protocols reference](https://docs.eco.com/sauce-sdk/reference/protocols.md).


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